@dbx-app/mcp-server 0.4.24 → 0.4.26
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 +155 -41
- package/package.json +2 -2
- package/server.json +2 -2
package/dist/index.js
CHANGED
|
@@ -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
|
|
74
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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;
|
|
@@ -151,8 +195,8 @@ export function createDbxMcpServer(backend, options = {}) {
|
|
|
151
195
|
results.push(await backend.executeQuery(withDatabase(scopedConfig, database ?? scope.database), statement));
|
|
152
196
|
}
|
|
153
197
|
if (results.length === 1)
|
|
154
|
-
return formatQueryToolResult(results[0]);
|
|
155
|
-
return
|
|
198
|
+
return labeledText(scopedConfig, formatQueryToolResult(results[0]).content[0].text);
|
|
199
|
+
return labeledText(scopedConfig, results.map((result, index) => formatQueryToolResult(result, `Statement ${index + 1}`).content[0].text).join("\n\n"));
|
|
156
200
|
}
|
|
157
201
|
catch (e) {
|
|
158
202
|
const msg = e instanceof Error ? e.message : String(e);
|
|
@@ -160,11 +204,12 @@ export function createDbxMcpServer(backend, options = {}) {
|
|
|
160
204
|
}
|
|
161
205
|
});
|
|
162
206
|
server.tool("dbx_execute_redis_command", "Execute a Redis command on a Redis connection", {
|
|
207
|
+
connection_id: z.string().optional().describe("Unique ID of the DBX connection (use this to disambiguate when multiple connections share the same name)"),
|
|
163
208
|
connection_name: z.string().optional().describe("Name of the DBX Redis connection"),
|
|
164
209
|
db: z.number().int().min(0).optional().describe("Redis logical database number (default: scoped/default database or 0)"),
|
|
165
210
|
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);
|
|
211
|
+
}, async ({ connection_id, connection_name, db, command }) => {
|
|
212
|
+
const { config, error } = await resolveConnection(backend, scope, connection_id, connection_name);
|
|
168
213
|
if (error)
|
|
169
214
|
return error;
|
|
170
215
|
const scopedConfig = config;
|
|
@@ -181,7 +226,7 @@ export function createDbxMcpServer(backend, options = {}) {
|
|
|
181
226
|
const result = await backend.executeRedisCommand(scopedConfig, defaultRedisDb(scopedConfig, scope, db), command, {
|
|
182
227
|
skipSafetyCheck: safety.skipSafetyCheck,
|
|
183
228
|
});
|
|
184
|
-
return formatRedisCommandToolResult(result);
|
|
229
|
+
return labeledText(scopedConfig, formatRedisCommandToolResult(result).content[0].text);
|
|
185
230
|
}
|
|
186
231
|
catch (e) {
|
|
187
232
|
const msg = e instanceof Error ? e.message : String(e);
|
|
@@ -189,23 +234,25 @@ export function createDbxMcpServer(backend, options = {}) {
|
|
|
189
234
|
}
|
|
190
235
|
});
|
|
191
236
|
server.tool("dbx_get_schema_context", "Get compact table and column context for writing SQL", {
|
|
237
|
+
connection_id: z.string().optional().describe("Unique ID of the DBX connection (use this to disambiguate when multiple connections share the same name)"),
|
|
192
238
|
connection_name: z.string().optional().describe("Name of the DBX connection"),
|
|
193
239
|
database: z.string().optional().describe("Database name"),
|
|
194
240
|
schema: z.string().optional().describe("Schema name (default: public for PostgreSQL)"),
|
|
195
241
|
tables: z.array(z.string()).optional().describe("Specific table names to include"),
|
|
196
242
|
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);
|
|
243
|
+
}, async ({ connection_id, connection_name, database, schema, tables, max_tables }) => {
|
|
244
|
+
const { config, error } = await resolveConnection(backend, scope, connection_id, connection_name);
|
|
199
245
|
if (error)
|
|
200
246
|
return error;
|
|
201
|
-
const
|
|
247
|
+
const resolvedConfig = config;
|
|
248
|
+
const context = await buildSchemaContext(backend, withDatabase(resolvedConfig, database ?? scope.database), {
|
|
202
249
|
schema,
|
|
203
250
|
tables,
|
|
204
251
|
maxTables: max_tables,
|
|
205
252
|
});
|
|
206
253
|
if (context.tables.length === 0)
|
|
207
254
|
return text("No matching tables found.");
|
|
208
|
-
return
|
|
255
|
+
return labeledText(resolvedConfig, formatSchemaContext(context));
|
|
209
256
|
});
|
|
210
257
|
if (!scoped) {
|
|
211
258
|
server.tool("dbx_add_connection", "Add a new database connection to DBX", {
|
|
@@ -250,7 +297,35 @@ export function createDbxMcpServer(backend, options = {}) {
|
|
|
250
297
|
});
|
|
251
298
|
server.tool("dbx_remove_connection", "Remove a database connection from DBX", {
|
|
252
299
|
connection_name: z.string().describe("Name of the connection to remove"),
|
|
253
|
-
|
|
300
|
+
connection_id: z.string().optional().describe("Unique ID of the DBX connection (use this to remove by id instead of name)"),
|
|
301
|
+
}, async ({ connection_name, connection_id }) => {
|
|
302
|
+
if (connection_id?.trim()) {
|
|
303
|
+
if (backend.removeConnectionById) {
|
|
304
|
+
const removed = await backend.removeConnectionById(connection_id.trim());
|
|
305
|
+
if (!removed)
|
|
306
|
+
return toolError("CONNECTION_NOT_FOUND", `Connection with id "${connection_id}" not found.`);
|
|
307
|
+
await notifyReload();
|
|
308
|
+
return text(`Connection with id "${connection_id}" removed.`);
|
|
309
|
+
}
|
|
310
|
+
// Fallback: resolve by id then remove by name
|
|
311
|
+
const connections = await backend.loadConnections();
|
|
312
|
+
const config = connections.find((c) => c.id === connection_id.trim());
|
|
313
|
+
if (!config)
|
|
314
|
+
return toolError("CONNECTION_NOT_FOUND", `Connection with id "${connection_id}" not found.`);
|
|
315
|
+
const removed = await backend.removeConnection(config.name);
|
|
316
|
+
if (!removed)
|
|
317
|
+
return toolError("CONNECTION_NOT_FOUND", `Connection "${config.name}" could not be removed.`);
|
|
318
|
+
await notifyReload();
|
|
319
|
+
return text(`Connection "${config.name}" (id: ${config.id}) removed.`);
|
|
320
|
+
}
|
|
321
|
+
const allConnections = await backend.loadConnections();
|
|
322
|
+
const matching = allConnections.filter((c) => c.name.toLowerCase() === connection_name.toLowerCase());
|
|
323
|
+
if (matching.length === 0)
|
|
324
|
+
return toolError("CONNECTION_NOT_FOUND", `Connection "${connection_name}" not found.`);
|
|
325
|
+
if (matching.length > 1) {
|
|
326
|
+
const lines = matching.map((c) => `- ${c.id}: ${c.db_type} @ ${c.host}:${c.port}`);
|
|
327
|
+
return toolError("AMBIGUOUS_CONNECTION", `Multiple connections found with name "${connection_name}". Please specify connection_id:\n${lines.join("\n")}`);
|
|
328
|
+
}
|
|
254
329
|
const removed = await backend.removeConnection(connection_name);
|
|
255
330
|
if (!removed)
|
|
256
331
|
return toolError("CONNECTION_NOT_FOUND", `Connection "${connection_name}" not found.`);
|
|
@@ -261,24 +336,62 @@ export function createDbxMcpServer(backend, options = {}) {
|
|
|
261
336
|
// Desktop-only tools: open table and execute-and-show require the Tauri bridge
|
|
262
337
|
if (!isWebMode && !scoped) {
|
|
263
338
|
server.tool("dbx_open_table", "Open a table in DBX desktop app UI. Requires DBX to be running.", {
|
|
264
|
-
|
|
339
|
+
connection_id: z.string().optional().describe("Unique ID of the DBX connection (use this to disambiguate when multiple connections share the same name)"),
|
|
340
|
+
connection_name: z.string().optional().describe("Name of the DBX connection"),
|
|
265
341
|
table: z.string().describe("Table name to open"),
|
|
266
342
|
database: z.string().optional().describe("Database name"),
|
|
267
343
|
schema: z.string().optional().describe("Schema name"),
|
|
268
|
-
}, async ({ connection_name, table, database, schema }) => {
|
|
269
|
-
|
|
270
|
-
if (
|
|
271
|
-
|
|
272
|
-
|
|
344
|
+
}, async ({ connection_id, connection_name, table, database, schema }) => {
|
|
345
|
+
let config;
|
|
346
|
+
if (connection_id?.trim()) {
|
|
347
|
+
const connections = await backend.loadConnections();
|
|
348
|
+
config = connections.find((c) => c.id === connection_id.trim());
|
|
349
|
+
if (!config)
|
|
350
|
+
return toolError("CONNECTION_NOT_FOUND", `Connection with id "${connection_id}" not found.`);
|
|
351
|
+
}
|
|
352
|
+
else if (connection_name?.trim()) {
|
|
353
|
+
const connections = await backend.loadConnections();
|
|
354
|
+
const matching = connections.filter((c) => c.name.toLowerCase() === connection_name.toLowerCase());
|
|
355
|
+
if (matching.length === 0)
|
|
356
|
+
return toolError("CONNECTION_NOT_FOUND", `Connection "${connection_name}" not found.`);
|
|
357
|
+
if (matching.length > 1) {
|
|
358
|
+
const lines = matching.map((c) => `- ${c.id}: ${c.db_type} @ ${c.host}:${c.port}`);
|
|
359
|
+
return toolError("AMBIGUOUS_CONNECTION", `Multiple connections found with name "${connection_name}". Please specify connection_id:\n${lines.join("\n")}`);
|
|
360
|
+
}
|
|
361
|
+
config = matching[0];
|
|
362
|
+
}
|
|
363
|
+
else {
|
|
364
|
+
return toolError("CONNECTION_NOT_FOUND", "Either connection_id or connection_name is required.");
|
|
365
|
+
}
|
|
366
|
+
return bridgeRequest("/open-table", { connection_id: config.id, connection_name: config.name, table, database, schema }, `Opened ${table} in DBX`);
|
|
273
367
|
});
|
|
274
368
|
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
|
-
|
|
369
|
+
connection_id: z.string().optional().describe("Unique ID of the DBX connection (use this to disambiguate when multiple connections share the same name)"),
|
|
370
|
+
connection_name: z.string().optional().describe("Name of the DBX connection"),
|
|
276
371
|
sql: z.string().describe("SQL query to execute"),
|
|
277
372
|
database: z.string().optional().describe("Database name"),
|
|
278
|
-
}, async ({ connection_name, sql, database }) => {
|
|
279
|
-
|
|
280
|
-
if (
|
|
281
|
-
|
|
373
|
+
}, async ({ connection_id, connection_name, sql, database }) => {
|
|
374
|
+
let config;
|
|
375
|
+
if (connection_id?.trim()) {
|
|
376
|
+
const connections = await backend.loadConnections();
|
|
377
|
+
config = connections.find((c) => c.id === connection_id.trim());
|
|
378
|
+
if (!config)
|
|
379
|
+
return toolError("CONNECTION_NOT_FOUND", `Connection with id "${connection_id}" not found.`);
|
|
380
|
+
}
|
|
381
|
+
else if (connection_name?.trim()) {
|
|
382
|
+
const connections = await backend.loadConnections();
|
|
383
|
+
const matching = connections.filter((c) => c.name.toLowerCase() === connection_name.toLowerCase());
|
|
384
|
+
if (matching.length === 0)
|
|
385
|
+
return toolError("CONNECTION_NOT_FOUND", `Connection "${connection_name}" not found.`);
|
|
386
|
+
if (matching.length > 1) {
|
|
387
|
+
const lines = matching.map((c) => `- ${c.id}: ${c.db_type} @ ${c.host}:${c.port}`);
|
|
388
|
+
return toolError("AMBIGUOUS_CONNECTION", `Multiple connections found with name "${connection_name}". Please specify connection_id:\n${lines.join("\n")}`);
|
|
389
|
+
}
|
|
390
|
+
config = matching[0];
|
|
391
|
+
}
|
|
392
|
+
else {
|
|
393
|
+
return toolError("CONNECTION_NOT_FOUND", "Either connection_id or connection_name is required.");
|
|
394
|
+
}
|
|
282
395
|
const safetyOptions = sqlSafetyFromEnv();
|
|
283
396
|
if (config?.db_type === "mongodb") {
|
|
284
397
|
const aggregate = parseMongoAggregateCommand(sql);
|
|
@@ -296,7 +409,8 @@ export function createDbxMcpServer(backend, options = {}) {
|
|
|
296
409
|
// MongoDB shell commands bypass the SQL safety evaluator; pass MCP
|
|
297
410
|
// safety flags to the desktop executor for command-aware gating.
|
|
298
411
|
return bridgeRequest("/execute-query", {
|
|
299
|
-
|
|
412
|
+
connection_id: config.id,
|
|
413
|
+
connection_name: config.name,
|
|
300
414
|
sql,
|
|
301
415
|
database,
|
|
302
416
|
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.
|
|
3
|
+
"version": "0.4.26",
|
|
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.
|
|
33
|
+
"@dbx-app/node-core": "^0.4.26"
|
|
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.
|
|
9
|
+
"version": "0.4.26",
|
|
10
10
|
"packages": [
|
|
11
11
|
{
|
|
12
12
|
"registryType": "npm",
|
|
13
13
|
"identifier": "@dbx-app/mcp-server",
|
|
14
|
-
"version": "0.4.
|
|
14
|
+
"version": "0.4.26",
|
|
15
15
|
"transport": {
|
|
16
16
|
"type": "stdio"
|
|
17
17
|
}
|