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