@dbx-app/mcp-server 0.4.25 → 0.4.27

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/dist/index.js CHANGED
@@ -3,7 +3,7 @@ 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
5
  import { z } from "zod";
6
- import { buildSchemaContext, createBackend, evaluateRedisCommandSafety, evaluateMongoAggregateSafety, evaluateSqlSafety, formatCell, formatSchemaContext, isMainModule, mdTable, notifyReload, parseMongoAggregateCommand, postBridge, sqlSafetyFromEnv, splitSqlStatements, } from "@dbx-app/node-core";
6
+ import { buildSchemaContext, createBackend, evaluateRedisCommandSafety, evaluateMongoAggregateSafety, evaluateSqlSafety, formatCell, formatSchemaContext, isMainModule, mdTable, notifyReload, parseMongoAggregateCommand, assessProductionSql, isLikelyMongoMutation, isProductionDatabase, postBridge, sqlSafetyFromEnv, splitSqlStatements, } from "@dbx-app/node-core";
7
7
  const require = createRequire(import.meta.url);
8
8
  const packageJson = require("../package.json");
9
9
  export const DBX_MCP_PACKAGE_VERSION = packageJson.version ?? "0.0.0";
@@ -16,6 +16,22 @@ function toolError(code, message) {
16
16
  function withDatabase(config, database) {
17
17
  return database === undefined ? config : { ...config, database };
18
18
  }
19
+ function metadataScope(config, database, schema) {
20
+ if (config.db_type !== "dameng") {
21
+ return { config: withDatabase(config, database), schema };
22
+ }
23
+ // Dameng exposes tables under user-owned schemas rather than separate
24
+ // databases. Accept the legacy database argument as a schema, and default to
25
+ // the login user when neither argument is provided.
26
+ const resolvedSchema = schema?.trim() || database?.trim() || config.username?.trim() || undefined;
27
+ return { config, schema: resolvedSchema };
28
+ }
29
+ function connectionIdentity(config) {
30
+ return `${config.name} (${config.id}) [${config.db_type} @ ${config.host}:${config.port}]`;
31
+ }
32
+ function labeledText(config, body) {
33
+ return text(`[${connectionIdentity(config)}]\n${body}`);
34
+ }
19
35
  function formatQueryToolResult(result, title) {
20
36
  const prefix = title ? `${title}\n` : "";
21
37
  if (result.columns.length === 0)
@@ -66,12 +82,33 @@ async function loadScopedConnections(backend, scope) {
66
82
  return connections;
67
83
  return connections.filter((config) => connectionMatchesScope(config, scope));
68
84
  }
69
- async function resolveConnection(backend, scope, requestedName) {
85
+ async function resolveConnection(backend, scope, requestedId, requestedName) {
86
+ // connection_id takes priority over connection_name when both are provided.
87
+ if (requestedId?.trim()) {
88
+ const connections = await backend.loadConnections();
89
+ const config = connections.find((c) => c.id === requestedId.trim());
90
+ if (!config)
91
+ return { error: toolError("CONNECTION_NOT_FOUND", `Connection with id "${requestedId}" not found.`) };
92
+ // In scoped mode, verify the resolved connection is within the scope.
93
+ if (scopeEnabled(scope) && !connectionMatchesScope(config, scope)) {
94
+ return { error: toolError("CONNECTION_OUT_OF_SCOPE", `Connection "${requestedId}" is outside this DBX AI session scope.`) };
95
+ }
96
+ return { config };
97
+ }
70
98
  if (!scopeEnabled(scope)) {
71
99
  if (!requestedName?.trim())
72
100
  return { error: toolError("CONNECTION_NOT_FOUND", "Connection name is required.") };
73
- const config = await backend.findConnection(requestedName);
74
- return config ? { config } : { error: toolError("CONNECTION_NOT_FOUND", `Connection "${requestedName}" not found.`) };
101
+ const connections = await backend.loadConnections();
102
+ const matching = connections.filter((c) => c.name.toLowerCase() === requestedName.trim().toLowerCase());
103
+ if (matching.length === 0)
104
+ return { error: toolError("CONNECTION_NOT_FOUND", `Connection "${requestedName}" not found.`) };
105
+ if (matching.length > 1) {
106
+ const lines = matching.map((c) => `- ${c.id}: ${c.db_type} @ ${c.host}:${c.port}`);
107
+ return {
108
+ error: toolError("AMBIGUOUS_CONNECTION", `Multiple connections found with name "${requestedName}". Please specify connection_id:\n${lines.join("\n")}`),
109
+ };
110
+ }
111
+ return { config: matching[0] };
75
112
  }
76
113
  const [scopedConfig] = await loadScopedConnections(backend, scope);
77
114
  if (!scopedConfig)
@@ -93,44 +130,51 @@ export function createDbxMcpServer(backend, options = {}) {
93
130
  const connections = await loadScopedConnections(backend, scope);
94
131
  if (connections.length === 0)
95
132
  return text("No connections configured in DBX.");
96
- const rows = connections.map((c) => [c.name, c.db_type, c.host, String(c.port), c.database || ""]);
97
- return text(mdTable(["Name", "Type", "Host", "Port", "Database"], rows));
133
+ const rows = connections.map((c) => [c.id, c.name, c.db_type, c.host, String(c.port), c.database || ""]);
134
+ return text(mdTable(["ID", "Name", "Type", "Host", "Port", "Database"], rows));
98
135
  });
99
136
  server.tool("dbx_list_tables", "List tables and views for a database connection", {
137
+ connection_id: z.string().optional().describe("Unique ID of the DBX connection (use this to disambiguate when multiple connections share the same name)"),
100
138
  connection_name: z.string().optional().describe("Name of the DBX connection"),
101
- database: z.string().optional().describe("Database name"),
102
- schema: z.string().optional().describe("Schema name (default: public for PostgreSQL)"),
103
- }, async ({ connection_name, database, schema }) => {
104
- const { config, error } = await resolveConnection(backend, scope, connection_name);
139
+ database: z.string().optional().describe("Database name; for Dameng this is also accepted as a schema alias"),
140
+ schema: z.string().optional().describe("Schema name (default: public for PostgreSQL, login user for Dameng)"),
141
+ }, async ({ connection_id, connection_name, database, schema }) => {
142
+ const { config, error } = await resolveConnection(backend, scope, connection_id, connection_name);
105
143
  if (error)
106
144
  return error;
107
- const tables = await backend.listTables(withDatabase(config, database ?? scope.database), schema);
145
+ const resolvedConfig = config;
146
+ const scopeValue = metadataScope(resolvedConfig, database ?? scope.database, schema);
147
+ const tables = await backend.listTables(scopeValue.config, scopeValue.schema);
108
148
  if (tables.length === 0)
109
149
  return text("No tables found.");
110
150
  const rows = tables.map((t) => [t.name, t.type]);
111
- return text(mdTable(["Table", "Type"], rows));
151
+ return labeledText(resolvedConfig, mdTable(["Table", "Type"], rows));
112
152
  });
113
153
  server.tool("dbx_describe_table", "Get column definitions for a table", {
154
+ connection_id: z.string().optional().describe("Unique ID of the DBX connection (use this to disambiguate when multiple connections share the same name)"),
114
155
  connection_name: z.string().optional().describe("Name of the DBX connection"),
115
156
  table: z.string().describe("Table name"),
116
- database: z.string().optional().describe("Database name"),
117
- schema: z.string().optional().describe("Schema name (default: public for PostgreSQL)"),
118
- }, async ({ connection_name, table, database, schema }) => {
119
- const { config, error } = await resolveConnection(backend, scope, connection_name);
157
+ database: z.string().optional().describe("Database name; for Dameng this is also accepted as a schema alias"),
158
+ schema: z.string().optional().describe("Schema name (default: public for PostgreSQL, login user for Dameng)"),
159
+ }, async ({ connection_id, connection_name, table, database, schema }) => {
160
+ const { config, error } = await resolveConnection(backend, scope, connection_id, connection_name);
120
161
  if (error)
121
162
  return error;
122
- const columns = await backend.describeTable(withDatabase(config, database ?? scope.database), table, schema);
163
+ const resolvedConfig = config;
164
+ const scopeValue = metadataScope(resolvedConfig, database ?? scope.database, schema);
165
+ const columns = await backend.describeTable(scopeValue.config, table, scopeValue.schema);
123
166
  if (columns.length === 0)
124
167
  return text("No columns found.");
125
168
  const rows = columns.map((c) => [c.is_primary_key ? `${c.name} (PK)` : c.name, c.data_type, c.is_nullable ? "YES" : "NO", c.column_default ?? "", c.comment ?? ""]);
126
- return text(mdTable(["Column", "Type", "Nullable", "Default", "Comment"], rows));
169
+ return labeledText(resolvedConfig, mdTable(["Column", "Type", "Nullable", "Default", "Comment"], rows));
127
170
  });
128
171
  server.tool("dbx_execute_query", "Execute a SQL query on a database connection (max 100 rows returned)", {
172
+ connection_id: z.string().optional().describe("Unique ID of the DBX connection (use this to disambiguate when multiple connections share the same name)"),
129
173
  connection_name: z.string().optional().describe("Name of the DBX connection"),
130
174
  database: z.string().optional().describe("Database name"),
131
175
  sql: z.string().describe("SQL query to execute"),
132
- }, async ({ connection_name, database, sql }) => {
133
- const { config, error } = await resolveConnection(backend, scope, connection_name);
176
+ }, async ({ connection_id, connection_name, database, sql }) => {
177
+ const { config, error } = await resolveConnection(backend, scope, connection_id, connection_name);
134
178
  if (error)
135
179
  return error;
136
180
  const scopedConfig = config;
@@ -141,6 +185,13 @@ export function createDbxMcpServer(backend, options = {}) {
141
185
  const safety = evaluateSqlSafety(sql, { ...sqlSafetyFromEnv(), allowMultipleStatements: true });
142
186
  if (!safety.allowed)
143
187
  return toolError("SQL_BLOCKED", safety.reason ?? "SQL blocked.");
188
+ const production = assessProductionSql(sql, scopedConfig, database ?? scope.database ?? scopedConfig.database);
189
+ if (production.active && production.isMutation) {
190
+ return toolError("PRODUCTION_WRITE_BLOCKED", "MCP cannot execute writes against a production database. Return the SQL for a user to review and run in DBX.");
191
+ }
192
+ }
193
+ else if (isProductionDatabase(scopedConfig, database ?? scope.database ?? scopedConfig.database) && isLikelyMongoMutation(sql)) {
194
+ return toolError("PRODUCTION_WRITE_BLOCKED", "MCP cannot execute writes against a production database. Return the command for a user to review and run in DBX.");
144
195
  }
145
196
  // MongoDB shell commands don't fit the SQL safety evaluator; the backend
146
197
  // (node-core executeQuery) applies command-aware read/write gating.
@@ -151,8 +202,8 @@ export function createDbxMcpServer(backend, options = {}) {
151
202
  results.push(await backend.executeQuery(withDatabase(scopedConfig, database ?? scope.database), statement));
152
203
  }
153
204
  if (results.length === 1)
154
- return formatQueryToolResult(results[0]);
155
- return text(results.map((result, index) => formatQueryToolResult(result, `Statement ${index + 1}`).content[0].text).join("\n\n"));
205
+ return labeledText(scopedConfig, formatQueryToolResult(results[0]).content[0].text);
206
+ return labeledText(scopedConfig, results.map((result, index) => formatQueryToolResult(result, `Statement ${index + 1}`).content[0].text).join("\n\n"));
156
207
  }
157
208
  catch (e) {
158
209
  const msg = e instanceof Error ? e.message : String(e);
@@ -160,11 +211,12 @@ export function createDbxMcpServer(backend, options = {}) {
160
211
  }
161
212
  });
162
213
  server.tool("dbx_execute_redis_command", "Execute a Redis command on a Redis connection", {
214
+ connection_id: z.string().optional().describe("Unique ID of the DBX connection (use this to disambiguate when multiple connections share the same name)"),
163
215
  connection_name: z.string().optional().describe("Name of the DBX Redis connection"),
164
216
  db: z.number().int().min(0).optional().describe("Redis logical database number (default: scoped/default database or 0)"),
165
217
  command: z.string().describe("Redis command to execute, for example: GET mykey, INFO, or DBSIZE"),
166
- }, async ({ connection_name, db, command }) => {
167
- const { config, error } = await resolveConnection(backend, scope, connection_name);
218
+ }, async ({ connection_id, connection_name, db, command }) => {
219
+ const { config, error } = await resolveConnection(backend, scope, connection_id, connection_name);
168
220
  if (error)
169
221
  return error;
170
222
  const scopedConfig = config;
@@ -177,11 +229,14 @@ export function createDbxMcpServer(backend, options = {}) {
177
229
  const safety = evaluateRedisCommandSafety(command, sqlSafetyFromEnv());
178
230
  if (!safety.allowed)
179
231
  return toolError("REDIS_COMMAND_BLOCKED", safety.reason ?? "Redis command blocked.");
232
+ if (isProductionDatabase(scopedConfig, String(defaultRedisDb(scopedConfig, scope, db))) && safety.safety !== "allowed") {
233
+ return toolError("PRODUCTION_WRITE_BLOCKED", "MCP cannot execute write or dangerous Redis commands against a production database.");
234
+ }
180
235
  try {
181
236
  const result = await backend.executeRedisCommand(scopedConfig, defaultRedisDb(scopedConfig, scope, db), command, {
182
237
  skipSafetyCheck: safety.skipSafetyCheck,
183
238
  });
184
- return formatRedisCommandToolResult(result);
239
+ return labeledText(scopedConfig, formatRedisCommandToolResult(result).content[0].text);
185
240
  }
186
241
  catch (e) {
187
242
  const msg = e instanceof Error ? e.message : String(e);
@@ -189,23 +244,25 @@ export function createDbxMcpServer(backend, options = {}) {
189
244
  }
190
245
  });
191
246
  server.tool("dbx_get_schema_context", "Get compact table and column context for writing SQL", {
247
+ connection_id: z.string().optional().describe("Unique ID of the DBX connection (use this to disambiguate when multiple connections share the same name)"),
192
248
  connection_name: z.string().optional().describe("Name of the DBX connection"),
193
249
  database: z.string().optional().describe("Database name"),
194
250
  schema: z.string().optional().describe("Schema name (default: public for PostgreSQL)"),
195
251
  tables: z.array(z.string()).optional().describe("Specific table names to include"),
196
252
  max_tables: z.number().int().min(1).max(20).default(8).describe("Maximum number of tables to include"),
197
- }, async ({ connection_name, database, schema, tables, max_tables }) => {
198
- const { config, error } = await resolveConnection(backend, scope, connection_name);
253
+ }, async ({ connection_id, connection_name, database, schema, tables, max_tables }) => {
254
+ const { config, error } = await resolveConnection(backend, scope, connection_id, connection_name);
199
255
  if (error)
200
256
  return error;
201
- const context = await buildSchemaContext(backend, withDatabase(config, database ?? scope.database), {
257
+ const resolvedConfig = config;
258
+ const context = await buildSchemaContext(backend, withDatabase(resolvedConfig, database ?? scope.database), {
202
259
  schema,
203
260
  tables,
204
261
  maxTables: max_tables,
205
262
  });
206
263
  if (context.tables.length === 0)
207
264
  return text("No matching tables found.");
208
- return text(formatSchemaContext(context));
265
+ return labeledText(resolvedConfig, formatSchemaContext(context));
209
266
  });
210
267
  if (!scoped) {
211
268
  server.tool("dbx_add_connection", "Add a new database connection to DBX", {
@@ -250,7 +307,35 @@ export function createDbxMcpServer(backend, options = {}) {
250
307
  });
251
308
  server.tool("dbx_remove_connection", "Remove a database connection from DBX", {
252
309
  connection_name: z.string().describe("Name of the connection to remove"),
253
- }, async ({ connection_name }) => {
310
+ connection_id: z.string().optional().describe("Unique ID of the DBX connection (use this to remove by id instead of name)"),
311
+ }, async ({ connection_name, connection_id }) => {
312
+ if (connection_id?.trim()) {
313
+ if (backend.removeConnectionById) {
314
+ const removed = await backend.removeConnectionById(connection_id.trim());
315
+ if (!removed)
316
+ return toolError("CONNECTION_NOT_FOUND", `Connection with id "${connection_id}" not found.`);
317
+ await notifyReload();
318
+ return text(`Connection with id "${connection_id}" removed.`);
319
+ }
320
+ // Fallback: resolve by id then remove by name
321
+ const connections = await backend.loadConnections();
322
+ const config = connections.find((c) => c.id === connection_id.trim());
323
+ if (!config)
324
+ return toolError("CONNECTION_NOT_FOUND", `Connection with id "${connection_id}" not found.`);
325
+ const removed = await backend.removeConnection(config.name);
326
+ if (!removed)
327
+ return toolError("CONNECTION_NOT_FOUND", `Connection "${config.name}" could not be removed.`);
328
+ await notifyReload();
329
+ return text(`Connection "${config.name}" (id: ${config.id}) removed.`);
330
+ }
331
+ const allConnections = await backend.loadConnections();
332
+ const matching = allConnections.filter((c) => c.name.toLowerCase() === connection_name.toLowerCase());
333
+ if (matching.length === 0)
334
+ return toolError("CONNECTION_NOT_FOUND", `Connection "${connection_name}" not found.`);
335
+ if (matching.length > 1) {
336
+ const lines = matching.map((c) => `- ${c.id}: ${c.db_type} @ ${c.host}:${c.port}`);
337
+ return toolError("AMBIGUOUS_CONNECTION", `Multiple connections found with name "${connection_name}". Please specify connection_id:\n${lines.join("\n")}`);
338
+ }
254
339
  const removed = await backend.removeConnection(connection_name);
255
340
  if (!removed)
256
341
  return toolError("CONNECTION_NOT_FOUND", `Connection "${connection_name}" not found.`);
@@ -261,24 +346,62 @@ export function createDbxMcpServer(backend, options = {}) {
261
346
  // Desktop-only tools: open table and execute-and-show require the Tauri bridge
262
347
  if (!isWebMode && !scoped) {
263
348
  server.tool("dbx_open_table", "Open a table in DBX desktop app UI. Requires DBX to be running.", {
264
- connection_name: z.string().describe("Name of the DBX connection"),
349
+ connection_id: z.string().optional().describe("Unique ID of the DBX connection (use this to disambiguate when multiple connections share the same name)"),
350
+ connection_name: z.string().optional().describe("Name of the DBX connection"),
265
351
  table: z.string().describe("Table name to open"),
266
352
  database: z.string().optional().describe("Database name"),
267
353
  schema: z.string().optional().describe("Schema name"),
268
- }, async ({ connection_name, table, database, schema }) => {
269
- const config = await backend.findConnection(connection_name);
270
- if (!config)
271
- return toolError("CONNECTION_NOT_FOUND", `Connection "${connection_name}" not found.`);
272
- return bridgeRequest("/open-table", { connection_name, table, database, schema }, `Opened ${table} in DBX`);
354
+ }, async ({ connection_id, connection_name, table, database, schema }) => {
355
+ let config;
356
+ if (connection_id?.trim()) {
357
+ const connections = await backend.loadConnections();
358
+ config = connections.find((c) => c.id === connection_id.trim());
359
+ if (!config)
360
+ return toolError("CONNECTION_NOT_FOUND", `Connection with id "${connection_id}" not found.`);
361
+ }
362
+ else if (connection_name?.trim()) {
363
+ const connections = await backend.loadConnections();
364
+ const matching = connections.filter((c) => c.name.toLowerCase() === connection_name.toLowerCase());
365
+ if (matching.length === 0)
366
+ return toolError("CONNECTION_NOT_FOUND", `Connection "${connection_name}" not found.`);
367
+ if (matching.length > 1) {
368
+ const lines = matching.map((c) => `- ${c.id}: ${c.db_type} @ ${c.host}:${c.port}`);
369
+ return toolError("AMBIGUOUS_CONNECTION", `Multiple connections found with name "${connection_name}". Please specify connection_id:\n${lines.join("\n")}`);
370
+ }
371
+ config = matching[0];
372
+ }
373
+ else {
374
+ return toolError("CONNECTION_NOT_FOUND", "Either connection_id or connection_name is required.");
375
+ }
376
+ return bridgeRequest("/open-table", { connection_id: config.id, connection_name: config.name, table, database, schema }, `Opened ${table} in DBX`);
273
377
  });
274
378
  server.tool("dbx_execute_and_show", "Execute a SQL query in DBX desktop app UI and show results there. Requires DBX to be running.", {
275
- connection_name: z.string().describe("Name of the DBX connection"),
379
+ connection_id: z.string().optional().describe("Unique ID of the DBX connection (use this to disambiguate when multiple connections share the same name)"),
380
+ connection_name: z.string().optional().describe("Name of the DBX connection"),
276
381
  sql: z.string().describe("SQL query to execute"),
277
382
  database: z.string().optional().describe("Database name"),
278
- }, async ({ connection_name, sql, database }) => {
279
- const config = await backend.findConnection(connection_name);
280
- if (!config)
281
- return toolError("CONNECTION_NOT_FOUND", `Connection "${connection_name}" not found.`);
383
+ }, async ({ connection_id, connection_name, sql, database }) => {
384
+ let config;
385
+ if (connection_id?.trim()) {
386
+ const connections = await backend.loadConnections();
387
+ config = connections.find((c) => c.id === connection_id.trim());
388
+ if (!config)
389
+ return toolError("CONNECTION_NOT_FOUND", `Connection with id "${connection_id}" not found.`);
390
+ }
391
+ else if (connection_name?.trim()) {
392
+ const connections = await backend.loadConnections();
393
+ const matching = connections.filter((c) => c.name.toLowerCase() === connection_name.toLowerCase());
394
+ if (matching.length === 0)
395
+ return toolError("CONNECTION_NOT_FOUND", `Connection "${connection_name}" not found.`);
396
+ if (matching.length > 1) {
397
+ const lines = matching.map((c) => `- ${c.id}: ${c.db_type} @ ${c.host}:${c.port}`);
398
+ return toolError("AMBIGUOUS_CONNECTION", `Multiple connections found with name "${connection_name}". Please specify connection_id:\n${lines.join("\n")}`);
399
+ }
400
+ config = matching[0];
401
+ }
402
+ else {
403
+ return toolError("CONNECTION_NOT_FOUND", "Either connection_id or connection_name is required.");
404
+ }
282
405
  const safetyOptions = sqlSafetyFromEnv();
283
406
  if (config?.db_type === "mongodb") {
284
407
  const aggregate = parseMongoAggregateCommand(sql);
@@ -293,10 +416,22 @@ export function createDbxMcpServer(backend, options = {}) {
293
416
  if (!safety.allowed)
294
417
  return toolError("SQL_BLOCKED", safety.reason ?? "SQL blocked.");
295
418
  }
419
+ if (config?.db_type === "mongodb") {
420
+ if (isProductionDatabase(config, database ?? scope.database ?? config.database) && isLikelyMongoMutation(sql)) {
421
+ return toolError("PRODUCTION_WRITE_BLOCKED", "MCP cannot send writes against a production database to DBX.");
422
+ }
423
+ }
424
+ else {
425
+ const production = assessProductionSql(sql, config, database ?? scope.database ?? config.database);
426
+ if (production.active && production.isMutation) {
427
+ return toolError("PRODUCTION_WRITE_BLOCKED", "MCP cannot send writes against a production database to DBX.");
428
+ }
429
+ }
296
430
  // MongoDB shell commands bypass the SQL safety evaluator; pass MCP
297
431
  // safety flags to the desktop executor for command-aware gating.
298
432
  return bridgeRequest("/execute-query", {
299
- connection_name,
433
+ connection_id: config.id,
434
+ connection_name: config.name,
300
435
  sql,
301
436
  database,
302
437
  allow_writes: safetyOptions.allowWrites,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dbx-app/mcp-server",
3
- "version": "0.4.25",
3
+ "version": "0.4.27",
4
4
  "description": "MCP server for DBX — query databases from Claude Code, Cursor, and other AI agents",
5
5
  "keywords": [
6
6
  "ai-agent",
@@ -30,7 +30,7 @@
30
30
  "dependencies": {
31
31
  "@modelcontextprotocol/sdk": "^1.12.1",
32
32
  "zod": "^3.25.20",
33
- "@dbx-app/node-core": "^0.4.25"
33
+ "@dbx-app/node-core": "^0.4.27"
34
34
  },
35
35
  "devDependencies": {
36
36
  "@types/node": "^22.15.21",
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.25",
9
+ "version": "0.4.27",
10
10
  "packages": [
11
11
  {
12
12
  "registryType": "npm",
13
13
  "identifier": "@dbx-app/mcp-server",
14
- "version": "0.4.25",
14
+ "version": "0.4.27",
15
15
  "transport": {
16
16
  "type": "stdio"
17
17
  }