mcp-db-analyzer 0.2.12 → 0.2.14

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.
@@ -23,7 +23,7 @@ export async function analyzeConnections() {
23
23
  }
24
24
  async function analyzePostgresConnections() {
25
25
  const lines = [`## Connection Analysis (PostgreSQL)\n`];
26
- const summary = await query(`SELECT COALESCE(state, 'null') AS state, COUNT(*)::text AS count
26
+ const summary = await query(`SELECT COALESCE(state, '(none)') AS state, COUNT(*)::text AS count
27
27
  FROM pg_stat_activity
28
28
  WHERE backend_type = 'client backend'
29
29
  GROUP BY state
@@ -34,7 +34,7 @@ async function analyzePostgresConnections() {
34
34
  let totalConnections = 0;
35
35
  for (const row of summary.rows) {
36
36
  lines.push(`| ${row.state} | ${row.count} |`);
37
- totalConnections += parseInt(row.count, 10);
37
+ totalConnections += parseInt(row.count, 10) || 0;
38
38
  }
39
39
  lines.push(`| **Total** | **${totalConnections}** |`);
40
40
  lines.push("");
@@ -158,7 +158,7 @@ async function analyzeMysqlConnections() {
158
158
  let total = 0;
159
159
  for (const row of summary.rows) {
160
160
  lines.push(`| ${row.state} | ${row.count} |`);
161
- total += parseInt(row.count, 10);
161
+ total += parseInt(row.count, 10) || 0;
162
162
  }
163
163
  lines.push(`| **Total** | **${total}** |`);
164
164
  lines.push("");
@@ -82,7 +82,7 @@ function formatIndexUsage(rows, schema) {
82
82
  return `No indexes found in schema '${schema}'.`;
83
83
  }
84
84
  const lines = [`## Index Usage Analysis — schema '${schema}'\n`];
85
- const unused = rows.filter((r) => r.idx_scan === "0");
85
+ const unused = rows.filter((r) => r.idx_scan === "0" || r.idx_scan == null);
86
86
  if (unused.length > 0) {
87
87
  lines.push(`### Unused Indexes (${unused.length} found)\n`);
88
88
  lines.push("These indexes have **zero scans** since the last stats reset. Consider dropping them to save space and speed up writes.\n");
@@ -56,7 +56,7 @@ async function suggestMissingIndexesSqlite() {
56
56
  WHERE type = 'index' AND tbl_name = ? AND name NOT LIKE 'sqlite_%'
57
57
  `, [table.name]);
58
58
  if (indexes.rows.length === 0) {
59
- const countResult = await query(`SELECT count(*) as cnt FROM "${table.name}"`);
59
+ const countResult = await query(`SELECT count(*) as cnt FROM "${table.name.replace(/"/g, '""')}"`);
60
60
  const cnt = countResult.rows[0]?.cnt ?? 0;
61
61
  if (cnt > 100) {
62
62
  tablesWithoutIndexes.push({
package/build/index.js CHANGED
@@ -248,7 +248,7 @@ server.tool("analyze_slow_queries", "Find the slowest queries using pg_stat_stat
248
248
  }
249
249
  });
250
250
  // Tool 7: analyze_connections
251
- server.tool("analyze_connections", "Analyze active database connections. Detects idle-in-transaction sessions (which hold locks and block other queries), long-running queries (flagged at >30 seconds), lock contention between sessions, and connection pool utilization. PostgreSQL and MySQL only.", {
251
+ server.tool("analyze_connections", "Analyze active database connections. Detects idle-in-transaction sessions and lock contention between sessions (PostgreSQL), long-running queries flagged at >30 seconds, and connection pool utilization. Idle-in-transaction and lock contention detection are not available on MySQL — use this tool's output to investigate PostgreSQL-specific blocking scenarios. Not available for SQLite.", {
252
252
  timeout_ms: timeoutParam,
253
253
  }, async ({ timeout_ms }) => {
254
254
  applyTimeout(timeout_ms);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mcp-db-analyzer",
3
- "version": "0.2.12",
3
+ "version": "0.2.14",
4
4
  "description": "MCP server for PostgreSQL, MySQL, and SQLite schema analysis, index optimization, and query plan inspection",
5
5
  "mcpName": "io.github.dmitriusan/mcp-db-analyzer",
6
6
  "author": "Dmytro Lisnichenko",