@neverinfamous/postgres-mcp 2.1.0 → 2.3.0

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.
Files changed (133) hide show
  1. package/README.md +78 -201
  2. package/dist/__tests__/benchmarks/codemode.bench.js +3 -3
  3. package/dist/__tests__/benchmarks/codemode.bench.js.map +1 -1
  4. package/dist/__tests__/benchmarks/connection-pool.bench.js +3 -3
  5. package/dist/__tests__/benchmarks/connection-pool.bench.js.map +1 -1
  6. package/dist/__tests__/benchmarks/introspection-migration.bench.d.ts +11 -0
  7. package/dist/__tests__/benchmarks/introspection-migration.bench.d.ts.map +1 -0
  8. package/dist/__tests__/benchmarks/introspection-migration.bench.js +143 -0
  9. package/dist/__tests__/benchmarks/introspection-migration.bench.js.map +1 -0
  10. package/dist/__tests__/benchmarks/resource-prompts.bench.js +0 -64
  11. package/dist/__tests__/benchmarks/resource-prompts.bench.js.map +1 -1
  12. package/dist/__tests__/benchmarks/schema-parsing.bench.js +4 -4
  13. package/dist/__tests__/benchmarks/schema-parsing.bench.js.map +1 -1
  14. package/dist/__tests__/benchmarks/tool-filtering.bench.js +17 -8
  15. package/dist/__tests__/benchmarks/tool-filtering.bench.js.map +1 -1
  16. package/dist/adapters/DatabaseAdapter.d.ts +0 -4
  17. package/dist/adapters/DatabaseAdapter.d.ts.map +1 -1
  18. package/dist/adapters/DatabaseAdapter.js +11 -28
  19. package/dist/adapters/DatabaseAdapter.js.map +1 -1
  20. package/dist/adapters/postgresql/PostgresAdapter.d.ts +0 -4
  21. package/dist/adapters/postgresql/PostgresAdapter.d.ts.map +1 -1
  22. package/dist/adapters/postgresql/PostgresAdapter.js +3 -6
  23. package/dist/adapters/postgresql/PostgresAdapter.js.map +1 -1
  24. package/dist/adapters/postgresql/resources/capabilities.js +1 -1
  25. package/dist/adapters/postgresql/resources/cron.d.ts.map +1 -1
  26. package/dist/adapters/postgresql/resources/cron.js +2 -1
  27. package/dist/adapters/postgresql/resources/cron.js.map +1 -1
  28. package/dist/adapters/postgresql/schemas/core/queries.d.ts +4 -4
  29. package/dist/adapters/postgresql/schemas/core/transactions.d.ts +12 -0
  30. package/dist/adapters/postgresql/schemas/core/transactions.d.ts.map +1 -1
  31. package/dist/adapters/postgresql/schemas/core/transactions.js +18 -0
  32. package/dist/adapters/postgresql/schemas/core/transactions.js.map +1 -1
  33. package/dist/adapters/postgresql/schemas/index.d.ts +1 -1
  34. package/dist/adapters/postgresql/schemas/index.d.ts.map +1 -1
  35. package/dist/adapters/postgresql/schemas/index.js +1 -1
  36. package/dist/adapters/postgresql/schemas/index.js.map +1 -1
  37. package/dist/adapters/postgresql/schemas/introspection.d.ts +17 -37
  38. package/dist/adapters/postgresql/schemas/introspection.d.ts.map +1 -1
  39. package/dist/adapters/postgresql/schemas/introspection.js +73 -30
  40. package/dist/adapters/postgresql/schemas/introspection.js.map +1 -1
  41. package/dist/adapters/postgresql/schemas/partman.d.ts +1 -1
  42. package/dist/adapters/postgresql/schemas/vector.d.ts.map +1 -1
  43. package/dist/adapters/postgresql/schemas/vector.js +2 -4
  44. package/dist/adapters/postgresql/schemas/vector.js.map +1 -1
  45. package/dist/adapters/postgresql/tools/introspection/analysis.d.ts.map +1 -1
  46. package/dist/adapters/postgresql/tools/introspection/analysis.js +171 -139
  47. package/dist/adapters/postgresql/tools/introspection/analysis.js.map +1 -1
  48. package/dist/adapters/postgresql/tools/introspection/graph.d.ts +17 -1
  49. package/dist/adapters/postgresql/tools/introspection/graph.d.ts.map +1 -1
  50. package/dist/adapters/postgresql/tools/introspection/graph.js +55 -50
  51. package/dist/adapters/postgresql/tools/introspection/graph.js.map +1 -1
  52. package/dist/adapters/postgresql/tools/introspection/index.d.ts +9 -7
  53. package/dist/adapters/postgresql/tools/introspection/index.d.ts.map +1 -1
  54. package/dist/adapters/postgresql/tools/introspection/index.js +9 -14
  55. package/dist/adapters/postgresql/tools/introspection/index.js.map +1 -1
  56. package/dist/adapters/postgresql/tools/introspection/migration.d.ts +1 -1
  57. package/dist/adapters/postgresql/tools/introspection/migration.d.ts.map +1 -1
  58. package/dist/adapters/postgresql/tools/introspection/migration.js +75 -96
  59. package/dist/adapters/postgresql/tools/introspection/migration.js.map +1 -1
  60. package/dist/adapters/postgresql/tools/migration/index.d.ts +15 -0
  61. package/dist/adapters/postgresql/tools/migration/index.d.ts.map +1 -0
  62. package/dist/adapters/postgresql/tools/migration/index.js +23 -0
  63. package/dist/adapters/postgresql/tools/migration/index.js.map +1 -0
  64. package/dist/adapters/postgresql/tools/performance/anomaly-detection.d.ts +18 -0
  65. package/dist/adapters/postgresql/tools/performance/anomaly-detection.d.ts.map +1 -0
  66. package/dist/adapters/postgresql/tools/performance/anomaly-detection.js +546 -0
  67. package/dist/adapters/postgresql/tools/performance/anomaly-detection.js.map +1 -0
  68. package/dist/adapters/postgresql/tools/performance/diagnostics.d.ts +11 -0
  69. package/dist/adapters/postgresql/tools/performance/diagnostics.d.ts.map +1 -0
  70. package/dist/adapters/postgresql/tools/performance/diagnostics.js +342 -0
  71. package/dist/adapters/postgresql/tools/performance/diagnostics.js.map +1 -0
  72. package/dist/adapters/postgresql/tools/performance/index.d.ts +1 -1
  73. package/dist/adapters/postgresql/tools/performance/index.d.ts.map +1 -1
  74. package/dist/adapters/postgresql/tools/performance/index.js +7 -1
  75. package/dist/adapters/postgresql/tools/performance/index.js.map +1 -1
  76. package/dist/adapters/postgresql/tools/transactions.d.ts.map +1 -1
  77. package/dist/adapters/postgresql/tools/transactions.js +67 -2
  78. package/dist/adapters/postgresql/tools/transactions.js.map +1 -1
  79. package/dist/auth/scopes.d.ts.map +1 -1
  80. package/dist/auth/scopes.js +2 -0
  81. package/dist/auth/scopes.js.map +1 -1
  82. package/dist/cli.js +6 -0
  83. package/dist/cli.js.map +1 -1
  84. package/dist/codemode/api/aliases.d.ts.map +1 -1
  85. package/dist/codemode/api/aliases.js +5 -0
  86. package/dist/codemode/api/aliases.js.map +1 -1
  87. package/dist/codemode/api/index.d.ts +1 -0
  88. package/dist/codemode/api/index.d.ts.map +1 -1
  89. package/dist/codemode/api/index.js +3 -0
  90. package/dist/codemode/api/index.js.map +1 -1
  91. package/dist/codemode/api/maps.d.ts.map +1 -1
  92. package/dist/codemode/api/maps.js +21 -12
  93. package/dist/codemode/api/maps.js.map +1 -1
  94. package/dist/constants/ServerInstructions.d.ts +1 -1
  95. package/dist/constants/ServerInstructions.d.ts.map +1 -1
  96. package/dist/constants/ServerInstructions.js +16 -9
  97. package/dist/constants/ServerInstructions.js.map +1 -1
  98. package/dist/filtering/ToolConstants.d.ts +18 -18
  99. package/dist/filtering/ToolConstants.d.ts.map +1 -1
  100. package/dist/filtering/ToolConstants.js +43 -29
  101. package/dist/filtering/ToolConstants.js.map +1 -1
  102. package/dist/filtering/ToolFilter.d.ts +0 -32
  103. package/dist/filtering/ToolFilter.d.ts.map +1 -1
  104. package/dist/filtering/ToolFilter.js +0 -43
  105. package/dist/filtering/ToolFilter.js.map +1 -1
  106. package/dist/transports/http.d.ts +12 -0
  107. package/dist/transports/http.d.ts.map +1 -1
  108. package/dist/transports/http.js +19 -1
  109. package/dist/transports/http.js.map +1 -1
  110. package/dist/types/filtering.d.ts +1 -1
  111. package/dist/types/filtering.d.ts.map +1 -1
  112. package/dist/types/index.d.ts +2 -2
  113. package/dist/types/index.d.ts.map +1 -1
  114. package/dist/types/index.js.map +1 -1
  115. package/dist/types/mcp.d.ts +0 -21
  116. package/dist/types/mcp.d.ts.map +1 -1
  117. package/dist/types/schema.d.ts +0 -79
  118. package/dist/types/schema.d.ts.map +1 -1
  119. package/dist/utils/icons.d.ts.map +1 -1
  120. package/dist/utils/icons.js +5 -0
  121. package/dist/utils/icons.js.map +1 -1
  122. package/dist/utils/identifiers.d.ts.map +1 -1
  123. package/dist/utils/identifiers.js +6 -6
  124. package/dist/utils/identifiers.js.map +1 -1
  125. package/dist/utils/progress-utils.d.ts +1 -12
  126. package/dist/utils/progress-utils.d.ts.map +1 -1
  127. package/dist/utils/progress-utils.js +0 -18
  128. package/dist/utils/progress-utils.js.map +1 -1
  129. package/package.json +3 -3
  130. package/dist/utils/promptGenerator.d.ts +0 -20
  131. package/dist/utils/promptGenerator.d.ts.map +0 -1
  132. package/dist/utils/promptGenerator.js +0 -81
  133. package/dist/utils/promptGenerator.js.map +0 -1
@@ -0,0 +1,546 @@
1
+ /**
2
+ * PostgreSQL Performance Tools - Anomaly Detection
3
+ *
4
+ * Lightweight anomaly detectors that compare current state against
5
+ * historical baselines using PostgreSQL system views. Returns risk
6
+ * scores, trend analysis, and actionable recommendations.
7
+ *
8
+ * Tools:
9
+ * - pg_detect_query_anomalies: z-score analysis via pg_stat_statements
10
+ * - pg_detect_bloat_risk: multi-factor bloat risk scoring
11
+ * - pg_detect_connection_spike: connection concentration detection
12
+ */
13
+ import { z } from "zod";
14
+ import { readOnly } from "../../../../utils/annotations.js";
15
+ import { getToolIcons } from "../../../../utils/icons.js";
16
+ import { formatPostgresError } from "../core/error-helpers.js";
17
+ import { validateIdentifier } from "../../../../utils/identifiers.js";
18
+ const toNum = (val) => val === null || val === undefined ? 0 : Number(val);
19
+ const toStr = (val, fallback = "") => typeof val === "string" ? val : fallback;
20
+ /** Parse numeric param with NaN fallback to default */
21
+ const safeNum = (val, defaultVal) => {
22
+ if (val == null)
23
+ return defaultVal;
24
+ const n = Number(val);
25
+ return Number.isNaN(n) ? defaultVal : n;
26
+ };
27
+ function riskFromScore(score) {
28
+ if (score >= 80)
29
+ return "critical";
30
+ if (score >= 60)
31
+ return "high";
32
+ if (score >= 40)
33
+ return "moderate";
34
+ return "low";
35
+ }
36
+ // =============================================================================
37
+ // 1. pg_detect_query_anomalies
38
+ // =============================================================================
39
+ const QueryAnomaliesInputBase = z.object({
40
+ threshold: z
41
+ .any()
42
+ .optional()
43
+ .describe("Standard deviation multiplier for anomaly detection (default: 2.0)"),
44
+ minCalls: z
45
+ .any()
46
+ .optional()
47
+ .describe("Minimum call count to filter noise (default: 10)"),
48
+ });
49
+ const QueryAnomaliesInput = QueryAnomaliesInputBase.transform((data) => ({
50
+ threshold: Math.max(0.5, Math.min(10, safeNum(data.threshold, 2.0))),
51
+ minCalls: Math.max(1, Math.min(10000, safeNum(data.minCalls, 10))),
52
+ }));
53
+ export function createDetectQueryAnomaliesTool(adapter) {
54
+ return {
55
+ name: "pg_detect_query_anomalies",
56
+ description: "Detects queries deviating from their historical execution time norms " +
57
+ "using z-score analysis. Requires pg_stat_statements extension. " +
58
+ "Returns anomalous queries ranked by deviation severity with risk level.",
59
+ inputSchema: QueryAnomaliesInputBase.shape,
60
+ outputSchema: z.object({
61
+ anomalies: z.array(z.any()),
62
+ riskLevel: z.enum(["low", "moderate", "high", "critical"]),
63
+ totalAnalyzed: z.number(),
64
+ anomalyCount: z.number(),
65
+ summary: z.string(),
66
+ }),
67
+ group: "performance",
68
+ annotations: readOnly("Detect query anomalies"),
69
+ icons: getToolIcons("performance", readOnly("Detect query anomalies")),
70
+ handler: async (params, _context) => {
71
+ try {
72
+ const parsed = QueryAnomaliesInput.safeParse(params);
73
+ if (!parsed.success) {
74
+ return {
75
+ success: false,
76
+ error: `Validation error: ${parsed.error.issues.map((i) => i.message).join(", ")}`,
77
+ };
78
+ }
79
+ const { threshold, minCalls } = parsed.data;
80
+ // Check if pg_stat_statements is available
81
+ const extCheck = await adapter.executeQuery(`SELECT 1 FROM pg_extension WHERE extname = 'pg_stat_statements'`);
82
+ if (!extCheck.rows || extCheck.rows.length === 0) {
83
+ return {
84
+ success: false,
85
+ error: "pg_stat_statements extension is not installed. " +
86
+ "Install with: CREATE EXTENSION pg_stat_statements; " +
87
+ "(requires shared_preload_libraries configuration)",
88
+ suggestion: "Use pg_diagnose_database_performance for baseline-free health checks",
89
+ };
90
+ }
91
+ // Count total analyzed queries
92
+ const countResult = await adapter.executeQuery(`SELECT COUNT(*) AS total FROM pg_stat_statements WHERE calls >= ${String(minCalls)}`);
93
+ const totalAnalyzed = toNum(countResult.rows?.[0]?.["total"]);
94
+ // Find anomalous queries using z-score
95
+ const result = await adapter.executeQuery(`
96
+ SELECT
97
+ LEFT(query, 200) AS query_preview,
98
+ calls,
99
+ round(mean_exec_time::numeric, 3) AS mean_exec_time_ms,
100
+ round(stddev_exec_time::numeric, 3) AS stddev_exec_time_ms,
101
+ round((mean_exec_time / NULLIF(stddev_exec_time, 0))::numeric, 2) AS z_score,
102
+ round(total_exec_time::numeric, 2) AS total_exec_time_ms,
103
+ rows
104
+ FROM pg_stat_statements
105
+ WHERE calls >= ${String(minCalls)}
106
+ AND stddev_exec_time > 0
107
+ AND mean_exec_time > (stddev_exec_time * ${String(threshold)})
108
+ ORDER BY (mean_exec_time / NULLIF(stddev_exec_time, 0)) DESC
109
+ LIMIT 20
110
+ `);
111
+ const anomalies = (result.rows ?? []).map((row) => ({
112
+ queryPreview: toStr(row["query_preview"]),
113
+ calls: toNum(row["calls"]),
114
+ meanExecTimeMs: toNum(row["mean_exec_time_ms"]),
115
+ stddevExecTimeMs: toNum(row["stddev_exec_time_ms"]),
116
+ zScore: toNum(row["z_score"]),
117
+ totalExecTimeMs: toNum(row["total_exec_time_ms"]),
118
+ rows: toNum(row["rows"]),
119
+ }));
120
+ const anomalyCount = anomalies.length;
121
+ const maxZScore = anomalies.length > 0 ? (anomalies[0]?.zScore ?? 0) : 0;
122
+ // Risk based on count and severity
123
+ let riskScore = 0;
124
+ if (anomalyCount >= 10)
125
+ riskScore += 40;
126
+ else if (anomalyCount >= 5)
127
+ riskScore += 25;
128
+ else if (anomalyCount >= 1)
129
+ riskScore += 10;
130
+ if (maxZScore >= 10)
131
+ riskScore += 50;
132
+ else if (maxZScore >= 5)
133
+ riskScore += 30;
134
+ else if (maxZScore >= 3)
135
+ riskScore += 15;
136
+ const riskLevel = riskFromScore(riskScore);
137
+ const summary = anomalyCount === 0
138
+ ? `No query anomalies detected (analyzed ${String(totalAnalyzed)} queries with threshold ${String(threshold)}σ)`
139
+ : `${String(anomalyCount)} anomalous queries detected out of ${String(totalAnalyzed)} analyzed (threshold: ${String(threshold)}σ, max z-score: ${String(maxZScore)})`;
140
+ return {
141
+ anomalies,
142
+ riskLevel,
143
+ totalAnalyzed,
144
+ anomalyCount,
145
+ summary,
146
+ };
147
+ }
148
+ catch (error) {
149
+ return {
150
+ success: false,
151
+ error: formatPostgresError(error, {
152
+ tool: "pg_detect_query_anomalies",
153
+ }),
154
+ };
155
+ }
156
+ },
157
+ };
158
+ }
159
+ // =============================================================================
160
+ // 2. pg_detect_bloat_risk
161
+ // =============================================================================
162
+ const BloatRiskInputBase = z.object({
163
+ schema: z
164
+ .string()
165
+ .optional()
166
+ .describe("Filter to a specific schema (default: all user schemas)"),
167
+ minRows: z
168
+ .any()
169
+ .optional()
170
+ .describe("Minimum live rows to include (default: 1000)"),
171
+ });
172
+ const BloatRiskInput = BloatRiskInputBase.transform((data) => ({
173
+ schema: data.schema,
174
+ minRows: Math.max(0, Math.min(1000000, safeNum(data.minRows, 1000))),
175
+ }));
176
+ export function createDetectBloatRiskTool(adapter) {
177
+ return {
178
+ name: "pg_detect_bloat_risk",
179
+ description: "Scores tables by bloat risk using multiple factors: dead tuple ratio, " +
180
+ "vacuum staleness, table size, and autovacuum effectiveness. " +
181
+ "Returns per-table risk scores (0-100) with actionable recommendations.",
182
+ inputSchema: BloatRiskInputBase.shape,
183
+ outputSchema: z.object({
184
+ tables: z.array(z.any()),
185
+ highRiskCount: z.number(),
186
+ totalAnalyzed: z.number(),
187
+ summary: z.string(),
188
+ }),
189
+ group: "performance",
190
+ annotations: readOnly("Detect bloat risk"),
191
+ icons: getToolIcons("performance", readOnly("Detect bloat risk")),
192
+ handler: async (params, _context) => {
193
+ try {
194
+ const parsed = BloatRiskInput.safeParse(params);
195
+ if (!parsed.success) {
196
+ return {
197
+ success: false,
198
+ error: `Validation error: ${parsed.error.issues.map((i) => i.message).join(", ")}`,
199
+ };
200
+ }
201
+ const { schema, minRows } = parsed.data;
202
+ let schemaFilter;
203
+ if (schema) {
204
+ validateIdentifier(schema);
205
+ schemaFilter = `AND schemaname = '${schema}'`;
206
+ }
207
+ else {
208
+ schemaFilter = `AND schemaname NOT IN ('pg_catalog', 'information_schema', 'cron', 'topology', 'tiger', 'tiger_data')`;
209
+ }
210
+ const result = await adapter.executeQuery(`
211
+ SELECT
212
+ schemaname AS schema,
213
+ relname AS table_name,
214
+ n_live_tup AS live_tuples,
215
+ n_dead_tup AS dead_tuples,
216
+ CASE WHEN n_live_tup + n_dead_tup > 0
217
+ THEN round((100.0 * n_dead_tup / (n_live_tup + n_dead_tup))::numeric, 2)
218
+ ELSE 0
219
+ END AS dead_pct,
220
+ pg_size_pretty(pg_total_relation_size(schemaname || '.' || relname)) AS total_size,
221
+ pg_total_relation_size(schemaname || '.' || relname) AS total_bytes,
222
+ last_vacuum,
223
+ last_autovacuum,
224
+ last_analyze,
225
+ last_autoanalyze,
226
+ vacuum_count,
227
+ autovacuum_count,
228
+ autoanalyze_count,
229
+ EXTRACT(EPOCH FROM (now() - COALESCE(last_autovacuum, last_vacuum)))::int AS seconds_since_vacuum
230
+ FROM pg_stat_user_tables
231
+ WHERE n_live_tup >= ${String(minRows)}
232
+ ${schemaFilter}
233
+ ORDER BY n_dead_tup DESC
234
+ LIMIT 50
235
+ `);
236
+ const rows = result.rows ?? [];
237
+ const tables = rows.map((row) => {
238
+ const liveTuples = toNum(row["live_tuples"]);
239
+ const deadTuples = toNum(row["dead_tuples"]);
240
+ const totalTuples = liveTuples + deadTuples;
241
+ const deadPct = toNum(row["dead_pct"]);
242
+ const totalBytes = toNum(row["total_bytes"]);
243
+ const secondsSinceVacuum = toNum(row["seconds_since_vacuum"]);
244
+ const autovacuumCount = toNum(row["autovacuum_count"]);
245
+ const autoanalyzeCount = toNum(row["autoanalyze_count"]);
246
+ // Risk scoring (0-100)
247
+ // Factor 1: Dead tuple ratio (35% weight)
248
+ let deadTupleScore = 0;
249
+ if (totalTuples > 0) {
250
+ const ratio = deadTuples / totalTuples;
251
+ if (ratio >= 0.5)
252
+ deadTupleScore = 100;
253
+ else if (ratio >= 0.3)
254
+ deadTupleScore = 80;
255
+ else if (ratio >= 0.1)
256
+ deadTupleScore = 50;
257
+ else if (ratio >= 0.05)
258
+ deadTupleScore = 25;
259
+ }
260
+ // Factor 2: Vacuum staleness (25% weight)
261
+ let vacuumStalenessScore = 0;
262
+ const hoursSinceVacuum = secondsSinceVacuum / 3600;
263
+ if (secondsSinceVacuum === 0 && deadTuples > 0) {
264
+ vacuumStalenessScore = 80; // Never vacuumed but has dead tuples
265
+ }
266
+ else if (hoursSinceVacuum >= 168) {
267
+ vacuumStalenessScore = 100; // > 7 days
268
+ }
269
+ else if (hoursSinceVacuum >= 72) {
270
+ vacuumStalenessScore = 70; // > 3 days
271
+ }
272
+ else if (hoursSinceVacuum >= 24) {
273
+ vacuumStalenessScore = 40; // > 1 day
274
+ }
275
+ // Factor 3: Table size blast radius (15% weight)
276
+ let sizeScore = 0;
277
+ const sizeMB = totalBytes / (1024 * 1024);
278
+ if (sizeMB >= 10000)
279
+ sizeScore = 100; // > 10 GB
280
+ else if (sizeMB >= 1000)
281
+ sizeScore = 70; // > 1 GB
282
+ else if (sizeMB >= 100)
283
+ sizeScore = 40; // > 100 MB
284
+ // Factor 4: Autovacuum effectiveness (25% weight)
285
+ let autovacuumScore = 0;
286
+ if (autovacuumCount === 0 && deadTuples > 0) {
287
+ autovacuumScore = 90; // Autovacuum never ran but has dead tuples
288
+ }
289
+ else if (autoanalyzeCount === 0 && liveTuples > 10000) {
290
+ autovacuumScore = 60; // Autoanalyze never ran on large table
291
+ }
292
+ const riskScore = Math.round(deadTupleScore * 0.35 +
293
+ vacuumStalenessScore * 0.25 +
294
+ sizeScore * 0.15 +
295
+ autovacuumScore * 0.25);
296
+ const recommendations = [];
297
+ if (deadPct >= 10) {
298
+ recommendations.push(`Run VACUUM ANALYZE on ${toStr(row["schema"])}.${toStr(row["table_name"])}`);
299
+ }
300
+ if (secondsSinceVacuum === 0 && deadTuples > 0) {
301
+ recommendations.push("Table has never been vacuumed — run VACUUM");
302
+ }
303
+ if (autovacuumCount === 0 && deadTuples > 1000) {
304
+ recommendations.push("Autovacuum has never run — check autovacuum settings");
305
+ }
306
+ if (hoursSinceVacuum >= 72 && deadTuples > 0) {
307
+ recommendations.push(`Last vacuum was ${String(Math.round(hoursSinceVacuum))}h ago — schedule more frequent vacuuming`);
308
+ }
309
+ return {
310
+ schema: toStr(row["schema"]),
311
+ tableName: toStr(row["table_name"]),
312
+ liveTuples,
313
+ deadTuples,
314
+ deadPct,
315
+ totalSize: toStr(row["total_size"], "0 bytes"),
316
+ lastVacuum: row["last_vacuum"],
317
+ lastAutovacuum: row["last_autovacuum"],
318
+ hoursSinceVacuum: Math.round(hoursSinceVacuum),
319
+ autovacuumCount,
320
+ riskScore,
321
+ riskLevel: riskFromScore(riskScore),
322
+ factors: {
323
+ deadTupleRatio: Math.round(deadTupleScore * 0.35),
324
+ vacuumStaleness: Math.round(vacuumStalenessScore * 0.25),
325
+ tableSizeImpact: Math.round(sizeScore * 0.15),
326
+ autovacuumEffectiveness: Math.round(autovacuumScore * 0.25),
327
+ },
328
+ recommendations,
329
+ };
330
+ });
331
+ // Sort by risk score descending
332
+ tables.sort((a, b) => b.riskScore - a.riskScore);
333
+ const highRiskCount = tables.filter((t) => t.riskScore >= 60).length;
334
+ const summary = highRiskCount === 0
335
+ ? `No high-risk bloat detected across ${String(tables.length)} tables`
336
+ : `${String(highRiskCount)} table(s) at high bloat risk out of ${String(tables.length)} analyzed`;
337
+ return {
338
+ tables,
339
+ highRiskCount,
340
+ totalAnalyzed: tables.length,
341
+ summary,
342
+ };
343
+ }
344
+ catch (error) {
345
+ return {
346
+ success: false,
347
+ error: formatPostgresError(error, {
348
+ tool: "pg_detect_bloat_risk",
349
+ }),
350
+ };
351
+ }
352
+ },
353
+ };
354
+ }
355
+ // =============================================================================
356
+ // 3. pg_detect_connection_spike
357
+ // =============================================================================
358
+ const ConnectionSpikeInputBase = z.object({
359
+ warningPercent: z
360
+ .any()
361
+ .optional()
362
+ .describe("Percentage threshold for flagging concentration (default: 70)"),
363
+ });
364
+ const ConnectionSpikeInput = ConnectionSpikeInputBase.transform((data) => ({
365
+ warningPercent: Math.max(10, Math.min(100, safeNum(data.warningPercent, 70))),
366
+ }));
367
+ export function createDetectConnectionSpikeTool(adapter) {
368
+ return {
369
+ name: "pg_detect_connection_spike",
370
+ description: "Detects unusual connection patterns by analyzing concentration " +
371
+ "by user, application, state, and wait events. Flags when a single " +
372
+ "user or application monopolizes the connection pool, or when " +
373
+ "idle-in-transaction connections accumulate.",
374
+ inputSchema: ConnectionSpikeInputBase.shape,
375
+ outputSchema: z.object({
376
+ totalConnections: z.number(),
377
+ maxConnections: z.number(),
378
+ usagePercent: z.number(),
379
+ byState: z.array(z.any()),
380
+ concentrations: z.array(z.any()),
381
+ warnings: z.array(z.string()),
382
+ riskLevel: z.enum(["low", "moderate", "high", "critical"]),
383
+ summary: z.string(),
384
+ }),
385
+ group: "performance",
386
+ annotations: readOnly("Detect connection spike"),
387
+ icons: getToolIcons("performance", readOnly("Detect connection spike")),
388
+ handler: async (params, _context) => {
389
+ try {
390
+ const parsed = ConnectionSpikeInput.safeParse(params);
391
+ if (!parsed.success) {
392
+ return {
393
+ success: false,
394
+ error: `Validation error: ${parsed.error.issues.map((i) => i.message).join(", ")}`,
395
+ };
396
+ }
397
+ const { warningPercent } = parsed.data;
398
+ // Gather connection data in parallel
399
+ const [stateResult, userResult, appResult, maxResult, idleTxResult] = await Promise.all([
400
+ // By state
401
+ adapter.executeQuery(`
402
+ SELECT state, count(*) AS count
403
+ FROM pg_stat_activity
404
+ WHERE pid != pg_backend_pid()
405
+ GROUP BY state
406
+ ORDER BY count DESC
407
+ `),
408
+ // By user
409
+ adapter.executeQuery(`
410
+ SELECT usename, count(*) AS count
411
+ FROM pg_stat_activity
412
+ WHERE pid != pg_backend_pid()
413
+ GROUP BY usename
414
+ ORDER BY count DESC
415
+ `),
416
+ // By application
417
+ adapter.executeQuery(`
418
+ SELECT COALESCE(application_name, '') AS app_name, count(*) AS count
419
+ FROM pg_stat_activity
420
+ WHERE pid != pg_backend_pid()
421
+ GROUP BY application_name
422
+ ORDER BY count DESC
423
+ `),
424
+ // Max connections
425
+ adapter.executeQuery(`SHOW max_connections`),
426
+ // Idle-in-transaction details
427
+ adapter.executeQuery(`
428
+ SELECT pid, usename,
429
+ COALESCE(application_name, '') AS app_name,
430
+ now() - state_change AS idle_duration,
431
+ EXTRACT(EPOCH FROM (now() - state_change))::int AS idle_seconds
432
+ FROM pg_stat_activity
433
+ WHERE state = 'idle in transaction'
434
+ AND pid != pg_backend_pid()
435
+ ORDER BY state_change ASC
436
+ LIMIT 20
437
+ `),
438
+ ]);
439
+ const byState = stateResult.rows ?? [];
440
+ const totalConnections = byState.reduce((sum, r) => sum + toNum(r["count"]), 0);
441
+ const maxConnections = toNum(maxResult.rows?.[0]?.["max_connections"]);
442
+ const usagePercent = maxConnections > 0
443
+ ? Math.round((totalConnections / maxConnections) * 100 * 10) / 10
444
+ : 0;
445
+ const concentrations = [];
446
+ const warnings = [];
447
+ // Check user concentration
448
+ for (const row of userResult.rows ?? []) {
449
+ const count = toNum(row["count"]);
450
+ const percent = totalConnections > 0
451
+ ? Math.round((count / totalConnections) * 100 * 10) / 10
452
+ : 0;
453
+ if (percent >= warningPercent) {
454
+ const user = toStr(row["usename"], "unknown");
455
+ concentrations.push({
456
+ dimension: "user",
457
+ value: user,
458
+ count,
459
+ percent,
460
+ });
461
+ warnings.push(`User '${user}' holds ${String(percent)}% of connections (${String(count)}/${String(totalConnections)})`);
462
+ }
463
+ }
464
+ // Check application concentration
465
+ for (const row of appResult.rows ?? []) {
466
+ const count = toNum(row["count"]);
467
+ const percent = totalConnections > 0
468
+ ? Math.round((count / totalConnections) * 100 * 10) / 10
469
+ : 0;
470
+ if (percent >= warningPercent) {
471
+ const app = toStr(row["app_name"]);
472
+ if (app) {
473
+ concentrations.push({
474
+ dimension: "application",
475
+ value: app,
476
+ count,
477
+ percent,
478
+ });
479
+ warnings.push(`Application '${app}' holds ${String(percent)}% of connections (${String(count)}/${String(totalConnections)})`);
480
+ }
481
+ }
482
+ }
483
+ // Check idle-in-transaction buildup
484
+ const idleTxRows = idleTxResult.rows ?? [];
485
+ if (idleTxRows.length > 0) {
486
+ const longIdleTx = idleTxRows.filter((r) => toNum(r["idle_seconds"]) > 300);
487
+ if (longIdleTx.length > 0) {
488
+ warnings.push(`${String(longIdleTx.length)} connection(s) idle in transaction for >5 minutes — these hold locks and block autovacuum`);
489
+ }
490
+ if (idleTxRows.length >= 5) {
491
+ warnings.push(`${String(idleTxRows.length)} total idle-in-transaction connections — check for uncommitted transactions`);
492
+ }
493
+ }
494
+ // Check overall pressure
495
+ if (usagePercent >= 90) {
496
+ warnings.push(`Critical connection pressure: ${String(usagePercent)}% of max_connections in use`);
497
+ }
498
+ else if (usagePercent >= 80) {
499
+ warnings.push(`High connection pressure: ${String(usagePercent)}% of max_connections in use`);
500
+ }
501
+ // Calculate risk level
502
+ let riskScore = 0;
503
+ if (usagePercent >= 90)
504
+ riskScore += 40;
505
+ else if (usagePercent >= 80)
506
+ riskScore += 25;
507
+ else if (usagePercent >= 70)
508
+ riskScore += 10;
509
+ if (concentrations.length >= 2)
510
+ riskScore += 30;
511
+ else if (concentrations.length >= 1)
512
+ riskScore += 15;
513
+ if (idleTxRows.length >= 5)
514
+ riskScore += 25;
515
+ else if (idleTxRows.length >= 1)
516
+ riskScore += 10;
517
+ const riskLevel = riskFromScore(riskScore);
518
+ const summary = warnings.length === 0
519
+ ? `No connection anomalies detected (${String(totalConnections)}/${String(maxConnections)} connections, ${String(usagePercent)}% usage)`
520
+ : `${String(warnings.length)} warning(s) detected: ${String(totalConnections)}/${String(maxConnections)} connections (${String(usagePercent)}% usage)`;
521
+ return {
522
+ totalConnections,
523
+ maxConnections,
524
+ usagePercent,
525
+ byState: byState.map((r) => ({
526
+ state: toStr(r["state"], "null"),
527
+ count: toNum(r["count"]),
528
+ })),
529
+ concentrations,
530
+ warnings,
531
+ riskLevel,
532
+ summary,
533
+ };
534
+ }
535
+ catch (error) {
536
+ return {
537
+ success: false,
538
+ error: formatPostgresError(error, {
539
+ tool: "pg_detect_connection_spike",
540
+ }),
541
+ };
542
+ }
543
+ },
544
+ };
545
+ }
546
+ //# sourceMappingURL=anomaly-detection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"anomaly-detection.js","sourceRoot":"","sources":["../../../../../src/adapters/postgresql/tools/performance/anomaly-detection.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * PostgreSQL Performance Tools - Database Diagnostics
3
+ *
4
+ * Consolidates key performance metrics into a single actionable report:
5
+ * slow queries, blocking locks, connection pressure, cache hit ratio,
6
+ * disk usage, and top tables by size/activity.
7
+ */
8
+ import type { PostgresAdapter } from "../../PostgresAdapter.js";
9
+ import type { ToolDefinition } from "../../../../types/index.js";
10
+ export declare function createDiagnoseTool(adapter: PostgresAdapter): ToolDefinition;
11
+ //# sourceMappingURL=diagnostics.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diagnostics.d.ts","sourceRoot":"","sources":["../../../../../src/adapters/postgresql/tools/performance/diagnostics.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,KAAK,EACV,cAAc,EAEf,MAAM,4BAA4B,CAAC;AAmWpC,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,eAAe,GAAG,cAAc,CAwG3E"}