mcp-postgres 4.0.4

High-performance MCP server for PostgreSQL with CPU-aware connection pooling and optimized buffers
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
[
  {
    "name": "execute_query",
    "description": "Execute a SELECT query and retrieve data as arrays. Supports all SELECT operations: filtering, aggregation, joins, subqueries, window functions, CTEs, UNION, INTERSECT, EXCEPT. Returns rows as arrays of column values. Maximum SQL length 10,000 characters. Use for data retrieval, analysis, reporting, and exploratory queries. SELECT queries only - no INSERT/UPDATE/DELETE allowed.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "sql": {"type": "string", "description": "SELECT SQL query (required). Max 10,000 chars. Examples: 'SELECT * FROM users LIMIT 10', 'SELECT u.id, COUNT(o.id) as order_count FROM users u LEFT JOIN orders o ON u.id=o.user_id GROUP BY u.id'. Must start with SELECT."}
      },
      "required": ["sql"]
    }
  },
  {
    "name": "execute_insert",
    "description": "Execute INSERT statement to add new records. Returns number of rows affected. Supports single row, multi-row, and SELECT-based inserts. Supports RETURNING clause to get inserted IDs or values. Use for adding new data, bulk imports, migrations, data loading. Max SQL length 10,000 characters.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "sql": {"type": "string", "description": "INSERT SQL statement (required). Max 10,000 chars. Examples: 'INSERT INTO users (email, name) VALUES (''a@x.com'', ''Alice'')', 'INSERT INTO users SELECT * FROM staging WHERE active=true RETURNING id'. Use RETURNING to get inserted IDs."}
      },
      "required": ["sql"]
    }
  },
  {
    "name": "execute_update",
    "description": "Execute UPDATE statement to modify existing records. Returns number of rows affected. ALWAYS requires WHERE clause to prevent accidental full-table updates. Supports RETURNING clause to verify changes. Use for data corrections, status changes, bulk updates. Max SQL length 10,000 characters. CRITICAL: Include WHERE clause or transaction will fail.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "sql": {"type": "string", "description": "UPDATE SQL with WHERE clause (required). Max 10,000 chars. Examples: 'UPDATE users SET status=''active'' WHERE created_at > now()-interval ''7 days''', 'UPDATE orders SET shipped_at=now() WHERE status=''ready'' RETURNING id'. MUST include WHERE clause to prevent accidental updates of all rows."}
      },
      "required": ["sql"]
    }
  },
  {
    "name": "execute_delete",
    "description": "Execute DELETE statement to remove records. Returns number of rows deleted. ALWAYS requires WHERE clause - deleting without one removes ALL rows and is dangerous. Supports RETURNING clause to show which rows were deleted. Use CAREFULLY. Consider soft-delete (UPDATE status='deleted') for critical data. Max SQL length 10,000 characters.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "sql": {"type": "string", "description": "DELETE SQL with WHERE clause (required). Max 10,000 chars. Examples: 'DELETE FROM audit_logs WHERE created_at < now()-interval ''90 days''', 'DELETE FROM temp_uploads WHERE status=''failed'' RETURNING id'. CRITICAL: ALWAYS include WHERE clause or all rows will be deleted."}
      },
      "required": ["sql"]
    }
  },
  {
    "name": "async_execute_insert",
    "description": "High-performance INSERT with synchronous_commit=OFF for bulk operations (100+ rows). Much faster than execute_insert when WHERE predicate affects many rows. Trades immediate durability for speed - data persisted but not guaranteed on disk immediately. Returns rows affected. Use for bulk imports, data migrations, high-volume inserts. Optimal when WHERE affects 100+ rows.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "sql": {"type": "string", "description": "INSERT SQL statement (required). Max 10,000 chars. Optimized when affecting 100+ rows. Examples: 'INSERT INTO users SELECT * FROM staging WHERE active=true', 'INSERT INTO archive (id, data) VALUES (1, ''d1''), (2, ''d2''), ... (500, ''d500'')'. Performance benefit significant for large batches."}
      },
      "required": ["sql"]
    }
  },
  {
    "name": "async_execute_update",
    "description": "High-performance UPDATE with synchronous_commit=OFF for bulk operations (100+ rows). Much faster than execute_update when WHERE condition matches many rows. Trades immediate durability for speed. ALWAYS requires WHERE clause to prevent full-table updates. Returns rows affected. Use for bulk updates, status changes, large-scale modifications.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "sql": {"type": "string", "description": "UPDATE SQL with WHERE clause (required). Max 10,000 chars. Optimized when WHERE affects 100+ rows. Examples: 'UPDATE users SET status=''inactive'' WHERE updated_at < now()-interval ''1 year''', 'UPDATE products SET price=price*1.1 WHERE category IN (1,2,3,4,5)'. MUST include WHERE clause. Performance benefit significant for large batches."}
      },
      "required": ["sql"]
    }
  },
  {
    "name": "async_execute_delete",
    "description": "High-performance DELETE with synchronous_commit=OFF for bulk operations (100+ rows). Much faster than execute_delete when WHERE condition matches many rows. Trades immediate durability for speed. ALWAYS requires WHERE clause - deleting without one removes ALL rows. Returns rows deleted. Use carefully for bulk deletes, archive cleanup, large-scale record removal.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "sql": {"type": "string", "description": "DELETE SQL with WHERE clause (required). Max 10,000 chars. Optimized when WHERE affects 100+ rows. Examples: 'DELETE FROM audit_logs WHERE created_at < now()-interval ''365 days''', 'DELETE FROM sessions WHERE expires_at < now()'. CRITICAL: ALWAYS include WHERE clause. Performance benefit significant for large batches."}
      },
      "required": ["sql"]
    }
  },
  {
    "name": "explain_query",
    "description": "Analyze query execution plans to understand performance. Shows how PostgreSQL executes a SELECT query: sequential vs index scans, join types, estimated rows. ANALYZE option executes query and shows actual metrics (execution time, actual rows, buffer usage). Use to identify missing indexes, inefficient joins, slow query plans. Output formats: JSON (machine-readable), TEXT (human-readable), YAML (structured text).",
    "inputSchema": {
      "type": "object",
      "properties": {
        "sql": {"type": "string", "description": "SELECT query to explain (required). Example: 'SELECT u.id, COUNT(o.id) FROM users u LEFT JOIN orders o ON u.id=o.user_id GROUP BY u.id HAVING COUNT(o.id) > 5'. Must be SELECT query."},
        "analyze": {"type": "boolean", "description": "Execute query and show actual metrics (optional, default: false). WARNING: Executes the query - avoid on slow queries. Shows real execution time, actual vs estimated rows, buffer usage. Use true to diagnose performance."},
        "buffers": {"type": "boolean", "description": "Include buffer usage statistics (optional, default: false). Requires analyze=true. Shows cache hits/misses and I/O stats. Useful for diagnosing cache efficiency and disk I/O bottlenecks."},
        "format": {"type": "string", "enum": ["json", "text", "yaml"], "description": "Output format (optional, default: 'json'). 'json'=machine-readable/parseable, 'text'=human-readable/visual, 'yaml'=structured/readable. Recommend 'text' for visual inspection, 'json' for analysis."}
      },
      "required": ["sql"]
    }
  },
  {
    "name": "list_tables",
    "description": "List all user-defined tables in the database with schema, name, and table type (BASE TABLE, TEMPORARY, etc). Excludes system tables from pg_catalog and information_schema. Use to discover available tables, understand database structure, identify tables available for querying or modification. Essential for schema exploration and data modeling.",
    "inputSchema": {
      "type": "object",
      "properties": {}
    }
  },
  {
    "name": "describe_table",
    "description": "Get detailed column information for a specific table: column names, data types, nullability, default values, column order. Shows all column metadata needed to understand table structure. Essential before querying or modifying data. Helps explore unfamiliar tables and verify schema assumptions. Returns columns as array with full metadata.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "table": {"type": "string", "description": "Table name to describe (required). Example: 'users', 'orders', 'products'. Case-insensitive. Use schema.table for non-public schemas."}
      },
      "required": ["table"]
    }
  },
  {
    "name": "list_schemas",
    "description": "List all non-system schemas in the database with owners. Shows organizational structure of database objects. Excludes system schemas (pg_catalog, information_schema, pg_toast). Useful for understanding multi-schema setups, permissions, and logical data organization. Essential for schema-aware object management.",
    "inputSchema": {
      "type": "object",
      "properties": {}
    }
  },
  {
    "name": "list_indexes",
    "description": "List all indexes in database with definitions, associated tables, columns, and types (UNIQUE, PARTIAL, EXPRESSION, etc). Shows CREATE INDEX statements that can be copied for replication. Use for index inventory, migration planning, understanding indexing strategy. Includes index size estimates and column ordering.",
    "inputSchema": {
      "type": "object",
      "properties": {}
    }
  },
  {
    "name": "list_triggers",
    "description": "List all triggers defined on a specific table with trigger names, event types (INSERT/UPDATE/DELETE), timing (BEFORE/AFTER), and action statements. Shows automated actions occurring when table data changes. Use to understand table behavior, debug unexpected changes, identify side effects of DML operations, understand cascade rules. Critical for understanding automation and data integrity logic.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "table": {"type": "string", "description": "Table name to show triggers for (required). Example: 'users', 'orders'. Case-insensitive."},
        "schema": {"type": "string", "description": "Schema name to filter triggers (optional, default: 'public'). Example: 'public', 'myschema'."},
        "limit": {"type": "integer", "description": "Max triggers to return (optional, default: 1000). Range: 1-10000. Prevents memory issues on tables with many triggers."}
      },
      "required": ["table"]
    }
  },
  {
    "name": "show_constraints",
    "description": "List all table constraints across database: PRIMARY KEY, FOREIGN KEY, UNIQUE, CHECK, and NOT NULL constraints. Shows constraint definitions and affected tables/columns. Use for understanding data integrity rules, dependency chains, constraint-driven optimizations. Essential for schema comprehension and migration planning.",
    "inputSchema": {
      "type": "object",
      "properties": {}
    }
  },
  {
    "name": "list_users",
    "description": "List all database users and roles with attributes: superuser status, can create databases, can create roles, can login, connection limits, validity expiration dates. Use for user administration auditing, understanding team access levels, identifying unused/expired accounts. Shows complete user metadata and permissions.",
    "inputSchema": {
      "type": "object",
      "properties": {}
    }
  },
  {
    "name": "list_user_privileges",
    "description": "List table-level privileges for a specific user or role showing which tables they can SELECT, INSERT, UPDATE, DELETE, REFERENCES, TRIGGER on. Use for auditing user permissions, understanding access control, verifying security policies. Shows grant status and grantor information.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "username": {"type": "string", "description": "Username or role name to check privileges for (required). Example: 'alice', 'readonly_role'. Case-insensitive."}
      },
      "required": ["username"]
    }
  },
  {
    "name": "list_role_memberships",
    "description": "Show role membership hierarchy - which users belong to which roles, admin grant options. Useful for understanding permission inheritance, group membership structure, organizational access patterns. Essential for permission auditing and understanding delegation. Shows complete role hierarchy.",
    "inputSchema": {
      "type": "object",
      "properties": {}
    }
  },
  {
    "name": "list_database_privileges",
    "description": "List database-level access control lists (ACLs) for all non-template databases. Shows which users/roles have which privileges (CONNECT, CREATE, TEMPORARY, etc) on each database. Use for auditing access control, understanding permission structure, verifying security policies at database level.",
    "inputSchema": {
      "type": "object",
      "properties": {}
    }
  },
  {
    "name": "show_current_user",
    "description": "Show information about the current database connection: authenticated username, current database name, PostgreSQL version with platform details, system information. Use to verify connection identity, check PostgreSQL version compatibility, understand session context. Helpful for debugging permission issues.",
    "inputSchema": {
      "type": "object",
      "properties": {}
    }
  },
  {
    "name": "show_session_info",
    "description": "Show current session connection details: current user, database, client IP and port, server address and port, application name. Useful for debugging connection issues, understanding session context in multi-client scenarios, auditing who is connected where. Shows complete network-level session information.",
    "inputSchema": {
      "type": "object",
      "properties": {}
    }
  },
  {
    "name": "list_connections",
    "description": "List all active database connections (excluding self) with PID, username, application name, state (active/idle/idle in transaction), connection start time, query start time. Use for monitoring active sessions, identifying long-running queries, understanding connection state. Essential for connection management and monitoring.",
    "inputSchema": {
      "type": "object",
      "properties": {}
    }
  },
  {
    "name": "show_running_queries",
    "description": "Show all non-idle queries currently executing: PID, username, application, state, full query text, start time. Use to identify long-running or problematic queries, monitor concurrent activity. Essential for live query monitoring and performance troubleshooting.",
    "inputSchema": {
      "type": "object",
      "properties": {}
    }
  },
  {
    "name": "show_connection_summary",
    "description": "Aggregate connection counts by state (active, idle, idle in transaction, etc). Provides high-level connection summary without listing individual connections. Use for quick connection health check, understanding load distribution.",
    "inputSchema": {
      "type": "object",
      "properties": {}
    }
  },
  {
    "name": "show_active_transactions",
    "description": "Show all transactions currently in progress: PID, username, application, state, transaction start time, query start time, full query. Essential for understanding transaction state, identifying blocking transactions, diagnosing transaction-related performance issues.",
    "inputSchema": {
      "type": "object",
      "properties": {}
    }
  },
  {
    "name": "show_locks",
    "description": "Show all locks held with lock holders and queries: lock PID, user, application, lock type (ExclusiveLock, ShareLock, etc), granted status, fastpath flag, query. Use to diagnose lock contention, understand blocking relationships, identify lock holders.",
    "inputSchema": {
      "type": "object",
      "properties": {}
    }
  },
  {
    "name": "show_waiting_locks",
    "description": "Show all locks waiting to be granted (not granted). Critical for diagnosing deadlocks and blocking: which transactions are waiting, what they're waiting for, lock types. Essential for resolving lock contention issues.",
    "inputSchema": {
      "type": "object",
      "properties": {}
    }
  },
  {
    "name": "show_deadlocks",
    "description": "Detect potential deadlock situations by identifying transactions in circular wait patterns. Shows which PIDs are involved, queries, timing. Use to identify and resolve deadlock conditions before they cause failures.",
    "inputSchema": {
      "type": "object",
      "properties": {}
    }
  },
  {
    "name": "analyze_table",
    "description": "Update table statistics for query optimizer. PostgreSQL uses these statistics to choose optimal query plans. Run after large data changes or before complex queries. Returns success/failure status and affected table name.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "table": {"type": "string", "description": "Table name to analyze (required). Example: 'users', 'orders'. Case-insensitive."}
      },
      "required": ["table"]
    }
  },
  {
    "name": "vacuum_analyze",
    "description": "Run VACUUM ANALYZE on specific table or entire database. VACUUM removes dead tuples and updates free space map. ANALYZE updates statistics. Combined operation optimizes storage and query performance. Use after large deletes or bulk operations. Omit table parameter to vacuum entire database.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "table": {"type": "string", "description": "Table name to vacuum (optional). Example: 'users'. Omit to vacuum entire database."}
      }
    }
  },
  {
    "name": "reindex_table",
    "description": "Rebuild all indexes on a table. Use when indexes become bloated, corrupted, or after major updates. Rebuilding improves performance and reclaims space. Locks table during operation - use CONCURRENTLY option for live tables.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "table": {"type": "string", "description": "Table name to reindex (required). Example: 'users', 'orders'. Case-insensitive."},
        "concurrent": {"type": "boolean", "description": "Use CONCURRENTLY to avoid blocking (optional, default: false). Slower but non-blocking for production tables."}
      },
      "required": ["table"]
    }
  },
  {
    "name": "reset_statistics",
    "description": "Reset all PostgreSQL statistics counters (pg_stat_statements, pg_stat_user_tables, pg_stat_user_indexes, etc). Use to clear old statistics and start fresh measurement. Useful for baseline measurement or after significant changes.",
    "inputSchema": {
      "type": "object",
      "properties": {}
    }
  },
  {
    "name": "analyze_db_health",
    "description": "Comprehensive one-stop health dashboard checking buffer cache hit ratios, active/idle connection counts, unused and duplicate indexes, VACUUM progress, tables needing maintenance, tables with excessive sequential scans. Runs multiple diagnostics and returns consolidated health status. Excellent for spotting performance issues and identifying optimization opportunities.",
    "inputSchema": {
      "type": "object",
      "properties": {}
    }
  },
  {
    "name": "list_unused_indexes",
    "description": "Identify indexes with zero scans (never used). Consume disk space, slow down writes, should be removed. Returns index metadata and size estimates. Review before removing to ensure not helping with index-only scans. Useful for cleanup and performance tuning.",
    "inputSchema": {
      "type": "object",
      "properties": {}
    }
  },
  {
    "name": "list_duplicate_indexes",
    "description": "Find redundant or duplicate indexes with overlapping functionality. Duplicate indexes waste storage and slow DML without query benefits. Shows candidates for consolidation/removal. Useful for index optimization and cleanup after schema changes.",
    "inputSchema": {
      "type": "object",
      "properties": {}
    }
  },
  {
    "name": "get_table_stats",
    "description": "Get live row counts, dead tuples, and vacuum history from pg_stat_user_tables for all tables. Shows table bloat indicators, live vs dead tuples, vacuum timing. Essential for identifying tables needing VACUUM and understanding table health.",
    "inputSchema": {
      "type": "object",
      "properties": {}
    }
  },
  {
    "name": "get_index_stats",
    "description": "Get index scan and tuple statistics from pg_stat_user_indexes for all indexes. Shows index usage patterns: scans, tuples read, tuples fetched. Essential for identifying unused/underused indexes and understanding index effectiveness.",
    "inputSchema": {
      "type": "object",
      "properties": {}
    }
  },
  {
    "name": "show_table_size",
    "description": "Get total size of each user table including indexes and TOAST storage. Shows table sizes as human-readable (MB/GB) and bytes. Use for identifying large tables, storage planning, capacity management.",
    "inputSchema": {
      "type": "object",
      "properties": {}
    }
  },
  {
    "name": "show_database_size",
    "description": "Get size of each database in bytes and human-readable format (MB/GB). Use for storage monitoring, capacity planning, database sizing decisions.",
    "inputSchema": {
      "type": "object",
      "properties": {}
    }
  },
  {
    "name": "get_cache_hit_ratio",
    "description": "Get buffer cache hit ratio (0-1.0 or 0-100%). Shows what percentage of data reads come from cache vs disk. High ratio (>0.95) indicates efficient caching. Low ratio suggests missing indexes, insufficient shared_buffers, or cold cache. Essential for I/O performance diagnosis.",
    "inputSchema": {
      "type": "object",
      "properties": {}
    }
  },
  {
    "name": "get_pg_stat_statements",
    "description": "Get top 50 slowest queries ranked by total execution time from pg_stat_statements extension. Shows query text, call count, mean/max/total execution time. Essential for identifying performance bottlenecks. Requires pg_stat_statements extension installed and enabled.",
    "inputSchema": {
      "type": "object",
      "properties": {}
    }
  },
  {
    "name": "get_setting",
    "description": "Retrieve specific PostgreSQL configuration setting with full metadata: current value, unit (bytes/seconds/etc), description, context (when changeable), default value. Use to inspect any configuration parameter. Helpful for understanding database tuning and current configuration state.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "setting_name": {"type": "string", "description": "PostgreSQL setting name (required). Examples: 'max_connections', 'shared_buffers', 'work_mem', 'effective_cache_size'. Case-insensitive. Returns value, unit, description, and context."}
      },
      "required": ["setting_name"]
    }
  },
  {
    "name": "show_all_settings",
    "description": "List all non-internal PostgreSQL settings with values, units, descriptions, and context. Shows complete configuration tuning surface. Useful for configuration review, audit, and understanding all available settings.",
    "inputSchema": {
      "type": "object",
      "properties": {}
    }
  },
  {
    "name": "show_memory_settings",
    "description": "Show key memory-related settings: shared_buffers (cache size), work_mem (operation workspace), maintenance_work_mem (VACUUM/CREATE INDEX memory), effective_cache_size (total available cache). Essential for tuning database performance.",
    "inputSchema": {
      "type": "object",
      "properties": {}
    }
  },
  {
    "name": "show_performance_settings",
    "description": "Show performance-related settings: max_connections, synchronous_commit, random_page_cost, effective_cache_size, work_mem. Essential for performance tuning and understanding current optimization level.",
    "inputSchema": {
      "type": "object",
      "properties": {}
    }
  },
  {
    "name": "show_log_settings",
    "description": "Show all logging-related settings: log_min_duration_statement, log_statement, log_connections, log_disconnections, log_duration. Useful for configuring audit logging and query monitoring.",
    "inputSchema": {
      "type": "object",
      "properties": {}
    }
  },
  {
    "name": "show_vacuum_progress",
    "description": "Monitor ongoing VACUUM and AUTOVACUUM operations in real-time. Shows which tables are being vacuumed, progress percentage, blocks processed, index vacuum count, estimated time remaining. Use to track maintenance operations and identify long-running vacuum processes impacting performance.",
    "inputSchema": {
      "type": "object",
      "properties": {}
    }
  },
  {
    "name": "show_transaction_isolation",
    "description": "Show current transaction isolation level (READ UNCOMMITTED, READ COMMITTED, REPEATABLE READ, SERIALIZABLE) and available levels. Use to understand current transaction safety level.",
    "inputSchema": {
      "type": "object",
      "properties": {}
    }
  },
  {
    "name": "show_transaction_timeout",
    "description": "Show current statement_timeout setting (maximum allowed query execution time). Use to verify query timeout configuration.",
    "inputSchema": {
      "type": "object",
      "properties": {}
    }
  },
  {
    "name": "show_autocommit_status",
    "description": "Show whether autocommit is enabled. Shows autocommit on/off status. Essential for understanding transaction behavior.",
    "inputSchema": {
      "type": "object",
      "properties": {}
    }
  },
  {
    "name": "show_replication_status",
    "description": "Show WAL replay status and uptime on replicas: whether WAL replay is paused, last WAL LSN received/replayed, uptime. Essential for monitoring replication health.",
    "inputSchema": {
      "type": "object",
      "properties": {}
    }
  },
  {
    "name": "list_replication_slots",
    "description": "List all replication slots (physical for streaming, logical for logical decoding). Shows slot name, type, database, active status, restart LSN, confirmed flush LSN. Use for replication monitoring and slot management.",
    "inputSchema": {
      "type": "object",
      "properties": {}
    }
  },
  {
    "name": "list_standby_servers",
    "description": "List connected standby servers with replication lag information. Shows client address, port, state (streaming/catchup), sync state (sync/async), write/flush/replay lag. Essential for monitoring streaming replication health.",
    "inputSchema": {
      "type": "object",
      "properties": {}
    }
  },
  {
    "name": "show_wal_info",
    "description": "Show current WAL (Write-Ahead Log) status: current LSN, insert LSN, replay paused flag, WAL size in bytes. Essential for understanding transaction log size and WAL archiving.",
    "inputSchema": {
      "type": "object",
      "properties": {}
    }
  },
  {
    "name": "show_base_backup_progress",
    "description": "Show base backup progress (PostgreSQL 17+): phase, total size, streamed size, tablespaces progress. Use to monitor full database backups.",
    "inputSchema": {
      "type": "object",
      "properties": {}
    }
  },
  {
    "name": "get_object_details",
    "description": "Get comprehensive information about specific table: all columns with types, primary key, foreign keys, all indexes, constraints, table size, row counts, descriptions. Complete schema information for thorough understanding. Returns everything needed to understand table role and relationships.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "table": {"type": "string", "description": "Table name to get details for (required). Example: 'users', 'orders'. Case-insensitive."},
        "schema": {"type": "string", "description": "Schema name (optional, default: 'public'). Example: 'public', 'staging'. Use schema.table format in table param to override."}
      },
      "required": ["table"]
    }
  },
  {
    "name": "create_table",
    "description": "Create a new table with specified columns and constraints. Define each column with type and optional constraints (PRIMARY KEY, UNIQUE, NOT NULL, DEFAULT, etc). Use for creating new tables with custom schemas. Max identifier length 255 characters.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "table": {"type": "string", "description": "Table name (required). Example: 'users', 'products'. Case-insensitive. Max 255 chars."},
        "columns": {"type": "array", "items": {"type": "string"}, "description": "Column definitions (required). Examples: ['id SERIAL PRIMARY KEY', 'email VARCHAR(255) UNIQUE NOT NULL', 'created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP']. Format: 'column_name TYPE [CONSTRAINT...]'"}
      },
      "required": ["table", "columns"]
    }
  },
  {
    "name": "drop_table",
    "description": "Drop (delete) a table and all its data permanently. Use IF EXISTS to avoid errors if table missing. Use CASCADE to also drop dependent objects (views, constraints). WARNING: Deletes all table data - use carefully.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "table": {"type": "string", "description": "Table name to drop (required). Example: 'users', 'temp_data'. Case-insensitive."},
        "if_exists": {"type": "boolean", "description": "Only drop if exists (optional, default: false). Use in cleanup scripts."},
        "cascade": {"type": "boolean", "description": "Also drop dependent views and constraints (optional, default: false). WARNING: Drops dependent views."}
      },
      "required": ["table"]
    }
  },
  {
    "name": "truncate_table",
    "description": "Quickly delete all rows from a table without deleting structure. Much faster than DELETE for clearing large tables. Use RESTART IDENTITY to reset auto-increment sequences. Use CASCADE for tables with foreign key constraints.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "table": {"type": "string", "description": "Table name to truncate (required). Example: 'temp_data', 'logs'. All rows deleted, structure remains."},
        "cascade": {"type": "boolean", "description": "Also truncate dependent tables (optional, default: false). Use when FK dependencies exist. Dangerous - affects related tables."},
        "restart_identity": {"type": "boolean", "description": "Reset auto-increment sequences (optional, default: false). For SERIAL/IDENTITY columns."}
      },
      "required": ["table"]
    }
  },
  {
    "name": "create_schema",
    "description": "Create a new schema (namespace for objects). Schemas organize tables, views, sequences into logical groups. Use IF NOT EXISTS to safely create if not present.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "schema_name": {"type": "string", "description": "Schema name (required). Example: 'analytics', 'reporting', 'archive'. Case-insensitive."},
        "if_not_exists": {"type": "boolean", "description": "Only create if doesn't exist (optional, default: false)."}
      },
      "required": ["schema_name"]
    }
  },
  {
    "name": "drop_schema",
    "description": "Drop (delete) a schema. Use IF EXISTS to avoid errors. Use CASCADE to drop all objects in schema.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "schema_name": {"type": "string", "description": "Schema name to drop (required). Example: 'analytics'. Case-insensitive."},
        "if_exists": {"type": "boolean", "description": "Only drop if exists (optional, default: false)."},
        "cascade": {"type": "boolean", "description": "Also drop all objects in schema (optional, default: false). WARNING: Drops all schema contents."}
      },
      "required": ["schema_name"]
    }
  },
  {
    "name": "create_view",
    "description": "Create a database view from a SELECT query. Views are virtual tables executing query each access. Use MATERIALIZED for performance (stores results), regular view for always-current data. Use OR REPLACE to update existing views.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "view_name": {"type": "string", "description": "View name (required). Example: 'user_summary', 'active_orders'. Case-insensitive."},
        "query": {"type": "string", "description": "SELECT query defining view (required). Example: 'SELECT id, name, COUNT(*) FROM users GROUP BY id, name'. Must be valid SELECT."},
        "materialized": {"type": "boolean", "description": "Create materialized view (stores results, fast, stale) vs regular (always current, slower) (optional, default: false). Materialized need REFRESH to update."},
        "or_replace": {"type": "boolean", "description": "Replace if exists (optional, default: false). For materialized, requires same columns/types."}
      },
      "required": ["view_name", "query"]
    }
  },
  {
    "name": "drop_view",
    "description": "Drop (delete) a view (regular or materialized). Use IF EXISTS to avoid errors. Use CASCADE to drop dependent views.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "view_name": {"type": "string", "description": "View name to drop (required). Example: 'user_summary'. Case-insensitive."},
        "if_exists": {"type": "boolean", "description": "Only drop if exists (optional, default: false)."},
        "cascade": {"type": "boolean", "description": "Also drop dependent views (optional, default: false). WARNING: Drops dependent views."}
      },
      "required": ["view_name"]
    }
  },
  {
    "name": "alter_view",
    "description": "Modify a view by renaming or changing schema. Use to reorganize views or fix naming.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "view_name": {"type": "string", "description": "View name to alter (required). Example: 'user_summary'."},
        "rename_to": {"type": "string", "description": "New name (optional). Example: 'users_summary'. Either this or set_schema required."},
        "set_schema": {"type": "string", "description": "New schema (optional). Example: 'analytics'. Either this or rename_to required."}
      },
      "required": ["view_name"]
    }
  },
  {
    "name": "create_index",
    "description": "Create a database index on columns for faster queries. Supports UNIQUE indexes for constraints and CONCURRENTLY for non-blocking creation on live tables. Use for optimizing slow queries or enforcing uniqueness. Max identifier 255 chars.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "index_name": {"type": "string", "description": "Index name (required). Example: 'idx_users_email'. Must be unique in schema."},
        "table": {"type": "string", "description": "Table name (required). Example: 'users', 'orders'. Case-insensitive."},
        "columns": {"type": "array", "items": {"type": "string"}, "description": "Column names (required). Example: ['email'] for single or ['user_id', 'created_at'] for composite. Order matters."},
        "unique": {"type": "boolean", "description": "Create UNIQUE index (optional, default: false). Enforces column uniqueness."},
        "concurrent": {"type": "boolean", "description": "Use CONCURRENTLY (optional, default: false). Non-blocking for live tables. Required for production."}
      },
      "required": ["index_name", "table", "columns"]
    }
  },
  {
    "name": "drop_index",
    "description": "Drop (delete) an index. Frees storage space and removes locking overhead. Use CONCURRENTLY on live tables. Safe to remove unused/duplicate indexes.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "index_name": {"type": "string", "description": "Index name to drop (required). Example: 'idx_users_email'. Must exist."},
        "if_exists": {"type": "boolean", "description": "Only drop if exists (optional, default: false). Use in scripts."},
        "concurrent": {"type": "boolean", "description": "Use CONCURRENTLY (optional, default: false). Non-blocking for live tables. Required for production."}
      },
      "required": ["index_name"]
    }
  },
  {
    "name": "alter_index",
    "description": "Modify an index by renaming or changing schema. Use to reorganize indexes or fix naming.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "index_name": {"type": "string", "description": "Index name to alter (required). Example: 'idx_users_email'."},
        "rename_to": {"type": "string", "description": "New name (optional). Example: 'idx_users_email_v2'. Either this or set_schema required."},
        "set_schema": {"type": "string", "description": "New schema (optional). Example: 'archive'. Either this or rename_to required."}
      },
      "required": ["index_name"]
    }
  },
  {
    "name": "create_sequence",
    "description": "Create a sequence for generating auto-incrementing values. Used for PRIMARY KEY values and counters. Sequences are independent objects shared across tables. Max identifier 255 chars.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "sequence_name": {"type": "string", "description": "Sequence name (required). Example: 'user_id_seq', 'order_seq'. Case-insensitive."},
        "if_not_exists": {"type": "boolean", "description": "Only create if doesn't exist (optional, default: false)."},
        "start": {"type": "integer", "description": "Starting value (optional, default: 1). Example: 100 starts from 100."},
        "increment": {"type": "integer", "description": "Increment by value (optional, default: 1). Example: 5 increments by 5."}
      },
      "required": ["sequence_name"]
    }
  },
  {
    "name": "drop_sequence",
    "description": "Drop (delete) a sequence. Use IF EXISTS to avoid errors if sequence missing.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "sequence_name": {"type": "string", "description": "Sequence name to drop (required). Example: 'user_id_seq'."},
        "if_exists": {"type": "boolean", "description": "Only drop if exists (optional, default: false)."}
      },
      "required": ["sequence_name"]
    }
  },
  {
    "name": "create_partition",
    "description": "Create a new partition for a partitioned table. Partitioning splits large tables for better performance. Supports RANGE (date ranges), LIST (discrete values), HASH (modulo) partitioning. Use for tables with millions of rows.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "table": {"type": "string", "description": "Parent partitioned table (required). Example: 'events'. Must be defined as partitioned."},
        "partition_name": {"type": "string", "description": "Partition name (required). Example: 'events_2026_01'. Convention: parent_partition_identifier."},
        "partition_type": {"type": "string", "enum": ["RANGE", "LIST", "HASH"], "description": "Partitioning strategy (required). RANGE=date/number ranges, LIST=specific values, HASH=modulo."},
        "column": {"type": "string", "description": "Partition column (required). Example: 'created_date'. Must match parent's partition column."},
        "values": {"type": "string", "description": "Partition bounds (required). Examples: 'FROM (2026-01-01) TO (2026-02-01)' for RANGE, 'IN (val1, val2)' for LIST, 'MODULUS 4 REMAINDER 0' for HASH."}
      },
      "required": ["table", "partition_name", "partition_type", "column", "values"]
    }
  },
  {
    "name": "drop_partition",
    "description": "Drop (delete) a partition from a partitioned table. Removes partition and all its data. Use carefully - deletes all partition rows. Use IF EXISTS to avoid errors.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "table": {"type": "string", "description": "Parent table (required). Example: 'events'. For context/logging."},
        "partition_name": {"type": "string", "description": "Partition name to drop (required). Example: 'events_2026_01'. Must be existing partition."},
        "if_exists": {"type": "boolean", "description": "Only drop if exists (optional, default: false). Use in cleanup scripts."}
      },
      "required": ["table", "partition_name"]
    }
  },
  {
    "name": "list_partitions",
    "description": "List all partitions of a partitioned table including names and sizes. Use to understand table partitioning structure.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "table": {"type": "string", "description": "Partitioned table (required). Example: 'events', 'logs'. Must be partitioned table."}
      },
      "required": ["table"]
    }
  },
  {
    "name": "async_batch_insert",
    "description": "High-performance multi-row insert (max 1,000 rows) with synchronous_commit=OFF. Much faster than individual inserts for bulk loads. Returns rows affected and optionally inserted IDs via RETURNING. Perfect for CSV imports, test data, bulk operations.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "table": {"type": "string", "description": "Target table (required). Example: 'users', 'products'. Case-insensitive. Must exist with INSERT perms."},
        "columns": {"type": "array", "items": {"type": "string"}, "description": "Column names in order (required). Example: ['email', 'name', 'created_at']. Count must match row data."},
        "rows": {"type": "array", "items": {"type": "array"}, "description": "Rows to insert (required). Max 1,000 rows. Each row is array of values. Example: [['a@x.com', 'Alice', '2026-01-01'], ['b@x.com', 'Bob', '2026-01-02']]."},
        "returning": {"type": "string", "description": "Column to return (optional). Example: 'id' returns inserted IDs. Useful for getting auto-generated IDs."}
      },
      "required": ["table", "columns", "rows"]
    }
  },
  {
    "name": "async_batch_insert_copy",
    "description": "Ultra-high-performance bulk insert (10K+ rows) using automatic batching. Much faster than async_batch_insert for massive imports. Returns total rows affected and batch count. Perfect for data warehouse loads, ETL, large migrations.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "table": {"type": "string", "description": "Target table (required). Example: 'users', 'events'. Case-insensitive. Should be empty for best performance."},
        "columns": {"type": "array", "items": {"type": "string"}, "description": "Column names in order (required). Example: ['id', 'event_type', 'timestamp']. All must exist."},
        "rows": {"type": "array", "items": {"type": "array"}, "description": "Rows to insert (required). Can be huge (10K+, 100K+). Each row must have matching column count."},
        "batch_size": {"type": "integer", "description": "Rows per batch (optional, default: 1,000). Range: 100-5,000. Larger = faster but more memory. For 100K+ use 1,000-2,000."}
      },
      "required": ["table", "columns", "rows"]
    }
  },
  {
    "name": "async_batch_update",
    "description": "High-performance bulk update with multiple WHERE clauses (each applied independently) and synchronous_commit=OFF. Much faster than individual updates for bulk modifications. Returns total rows affected.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "table": {"type": "string", "description": "Target table (required). Example: 'users', 'orders'. Case-insensitive."},
        "updates": {"type": "object", "description": "Column→value mappings (required). Example: {'status': 'inactive'}. Columns being updated."},
        "where_clauses": {"type": "array", "items": {"type": "object", "properties": {"column": {"type": "string"}, "op": {"type": "string", "enum": ["=", "<", ">", "<=", ">=", "<>", "IN", "LIKE"]}, "value": {}}}, "description": "Structured WHERE conditions (required). Example: [{'column': 'id', 'op': '=', 'value': 1}]. OR-combined. Operators: =, <, >, <=, >=, <>, IN, LIKE."}
      },
      "required": ["table", "updates", "where_clauses"]
    }
  },
  {
    "name": "async_batch_delete",
    "description": "High-performance bulk delete with OR-combined WHERE clauses and synchronous_commit=OFF. Much faster than individual deletes for bulk removal. Returns rows deleted. Supports RETURNING for verification.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "table": {"type": "string", "description": "Target table (required). Example: 'users', 'logs'. Case-insensitive."},
        "where_clauses": {"type": "array", "items": {"type": "object", "properties": {"column": {"type": "string"}, "op": {"type": "string", "enum": ["=", "<", ">", "<=", ">=", "<>", "IN", "LIKE"]}, "value": {}}}, "description": "Structured WHERE conditions (required). Example: [{'column': 'id', 'op': '=', 'value': 1}]. OR-combined. Operators: =, <, >, <=, >=, <>, IN, LIKE."},
        "returning": {"type": "string", "description": "Column to return (optional). Example: 'id'. Useful for verifying deletion."}
      },
      "required": ["table", "where_clauses"]
    }
  },
  {
    "name": "backup_table",
    "description": "Complete table backup copying columns, data, indexes, partitions. Creates backup_<table_name> with full schema preservation. All column definitions copied with types, defaults, nullability. All rows copied (complete dataset). All indexes recreated with same structure. Partition structure preserved. Essential safety - backup before DROP, bulk DELETE, schema changes. If original deleted: backup survives with all data. Complete recovery mechanism.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "table": {"type": "string", "description": "Table to backup (required). Example: 'users', 'orders'. Case-insensitive. Backup created as 'backup_users', 'backup_orders'."}
      },
      "required": ["table"]
    }
  },
  {
    "name": "create_user",
    "description": "Create a new PostgreSQL user (login role). Supports password, connection limits, login privilege, and expiration. Reduces typos vs raw SQL.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "username": {"type": "string", "description": "Username (required). 1-255 characters."},
        "password": {"type": "string", "description": "Password for the user (optional)."},
        "connection_limit": {"type": "integer", "description": "Max concurrent connections (optional). Default: unlimited."},
        "can_login": {"type": "boolean", "description": "Allow login (optional). Default: true."},
        "valid_until": {"type": "string", "description": "Expiry timestamp (optional). Example: '2027-01-01'."}
      },
      "required": ["username"]
    }
  },
  {
    "name": "alter_user",
    "description": "Modify an existing PostgreSQL user. Supports password change, rename, connection limits, login toggle, and expiry. Specify only the attributes to change.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "username": {"type": "string", "description": "Username to alter (required)."},
        "password": {"type": "string", "description": "New password (optional)."},
        "new_name": {"type": "string", "description": "Rename user to this name (optional)."},
        "connection_limit": {"type": "integer", "description": "New connection limit (optional)."},
        "can_login": {"type": "boolean", "description": "Toggle LOGIN/NOLOGIN (optional)."},
        "valid_until": {"type": "string", "description": "New expiry timestamp (optional). Example: '2027-01-01'."}
      },
      "required": ["username"]
    }
  },
  {
    "name": "drop_user",
    "description": "Drop a PostgreSQL user safely. Use if_exists to avoid errors if the user doesn't exist. Cannot drop users who own objects or have active connections.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "username": {"type": "string", "description": "Username to drop (required)."},
        "if_exists": {"type": "boolean", "description": "Add IF EXISTS clause (optional). Default: false."}
      },
      "required": ["username"]
    }
  },
  {
    "name": "create_role",
    "description": "Create a new PostgreSQL role. Roles can be login (user) or non-login (group) roles. Use with_login=true for user creation.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "role_name": {"type": "string", "description": "Role name (required). 1-255 characters."},
        "with_login": {"type": "boolean", "description": "Add LOGIN privilege (optional). Default: false (group role)."}
      },
      "required": ["role_name"]
    }
  },
  {
    "name": "alter_role",
    "description": "Modify a PostgreSQL role. Supports password, login privilege, superuser, createdb, and rename.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "role_name": {"type": "string", "description": "Role name to alter (required)."},
        "password": {"type": "string", "description": "New password (optional)."},
        "can_login": {"type": "boolean", "description": "Toggle LOGIN/NOLOGIN (optional)."},
        "superuser": {"type": "boolean", "description": "Toggle SUPERUSER/NOSUPERUSER (optional)."},
        "createdb": {"type": "boolean", "description": "Toggle CREATEDB/NOCREATEDB (optional)."},
        "new_name": {"type": "string", "description": "Rename role (optional)."}
      },
      "required": ["role_name"]
    }
  },
  {
    "name": "drop_role",
    "description": "Drop a PostgreSQL role safely. Use if_exists to avoid errors. Cannot drop roles with dependent objects.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "role_name": {"type": "string", "description": "Role name to drop (required)."},
        "if_exists": {"type": "boolean", "description": "Add IF EXISTS clause (optional). Default: false."}
      },
      "required": ["role_name"]
    }
  },
  {
    "name": "grant_privileges",
    "description": "Grant privileges on a database object to a user/role. Supports tables, sequences, schemas, databases, and ALL TABLES IN SCHEMA. Common privileges: SELECT, INSERT, UPDATE, DELETE, ALL.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "privilege": {"type": "string", "description": "Privilege to grant (required). Examples: 'SELECT', 'INSERT', 'UPDATE', 'DELETE', 'ALL'."},
        "object_type": {"type": "string", "description": "Object type (required). One of: 'table', 'sequence', 'schema', 'database', 'all_tables_in_schema'."},
        "object_name": {"type": "string", "description": "Object name (required). For all_tables_in_schema, use schema name."},
        "grantee": {"type": "string", "description": "User or role to grant to (required)."},
        "schema": {"type": "string", "description": "Schema name (optional). Default: 'public'."}
      },
      "required": ["privilege", "object_type", "object_name", "grantee"]
    }
  },
  {
    "name": "revoke_privileges",
    "description": "Revoke privileges on a database object from a user/role. Supports tables, sequences, schemas, databases, and ALL TABLES IN SCHEMA.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "privilege": {"type": "string", "description": "Privilege to revoke (required). Examples: 'SELECT', 'INSERT', 'ALL'."},
        "object_type": {"type": "string", "description": "Object type (required). One of: 'table', 'sequence', 'schema', 'database', 'all_tables_in_schema'."},
        "object_name": {"type": "string", "description": "Object name (required)."},
        "revokee": {"type": "string", "description": "User or role to revoke from (required)."},
        "schema": {"type": "string", "description": "Schema name (optional). Default: 'public'."}
      },
      "required": ["privilege", "object_type", "object_name", "revokee"]
    }
  },
  {
    "name": "add_column",
    "description": "Add a new column to an existing table. Supports data type, DEFAULT value, and NOT NULL constraint. Reduces ALTER TABLE syntax errors.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "table": {"type": "string", "description": "Table name (required). Example: 'users'."},
        "column": {"type": "string", "description": "Column name (required). Example: 'email'."},
        "data_type": {"type": "string", "description": "Column data type (required). Examples: 'TEXT', 'INTEGER', 'TIMESTAMP', 'VARCHAR(255)'."},
        "schema": {"type": "string", "description": "Schema name (optional). Default: 'public'."},
        "default": {"type": "string", "description": "DEFAULT value expression (optional). Example: 'now()', '0', ''guest''."},
        "not_null": {"type": "boolean", "description": "Add NOT NULL constraint (optional). Default: false."}
      },
      "required": ["table", "column", "data_type"]
    }
  },
  {
    "name": "drop_column",
    "description": "Remove a column from a table. Optionally use CASCADE to drop dependent objects. Irreversible - use with caution.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "table": {"type": "string", "description": "Table name (required)."},
        "column": {"type": "string", "description": "Column name to drop (required)."},
        "schema": {"type": "string", "description": "Schema name (optional). Default: 'public'."},
        "cascade": {"type": "boolean", "description": "Drop dependent objects (optional). Default: false."}
      },
      "required": ["table", "column"]
    }
  },
  {
    "name": "rename_column",
    "description": "Rename a column in an existing table. Non-disruptive operation that preserves data and constraints.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "table": {"type": "string", "description": "Table name (required)."},
        "column": {"type": "string", "description": "Current column name (required)."},
        "new_name": {"type": "string", "description": "New column name (required)."},
        "schema": {"type": "string", "description": "Schema name (optional). Default: 'public'."}
      },
      "required": ["table", "column", "new_name"]
    }
  },
  {
    "name": "alter_column_type",
    "description": "Change the data type of a column. Optionally provide a USING expression to transform existing data. May fail if data cannot be cast.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "table": {"type": "string", "description": "Table name (required)."},
        "column": {"type": "string", "description": "Column name (required)."},
        "data_type": {"type": "string", "description": "New data type (required). Examples: 'TEXT', 'BIGINT', 'TIMESTAMPTZ'."},
        "schema": {"type": "string", "description": "Schema name (optional). Default: 'public'."},
        "using": {"type": "string", "description": "USING expression for data conversion (optional). Example: 'column_name::BIGINT'."}
      },
      "required": ["table", "column", "data_type"]
    }
  },
  {
    "name": "rename_table",
    "description": "Rename a table. Updates all dependent views, foreign key references, and metadata automatically.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "table": {"type": "string", "description": "Current table name (required)."},
        "new_name": {"type": "string", "description": "New table name (required)."},
        "schema": {"type": "string", "description": "Schema name (optional). Default: 'public'."}
      },
      "required": ["table", "new_name"]
    }
  },
  {
    "name": "rename_index",
    "description": "Rename an index. Useful for adopting consistent naming conventions.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "index": {"type": "string", "description": "Current index name (required)."},
        "new_name": {"type": "string", "description": "New index name (required)."},
        "schema": {"type": "string", "description": "Schema name (optional). Default: 'public'."}
      },
      "required": ["index", "new_name"]
    }
  },
  {
    "name": "rename_schema",
    "description": "Rename a schema. All objects within the schema are automatically moved.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "schema": {"type": "string", "description": "Current schema name (required)."},
        "new_name": {"type": "string", "description": "New schema name (required)."}
      },
      "required": ["schema", "new_name"]
    }
  },
  {
    "name": "add_foreign_key",
    "description": "Add a foreign key constraint to a table. Prevents orphaned records and enforces referential integrity. Supports ON DELETE and ON UPDATE actions.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "table": {"type": "string", "description": "Child table (required)."},
        "columns": {"type": "string", "description": "Child column(s) (required). Comma-separated. Example: 'user_id' or 'col1, col2'."},
        "ref_table": {"type": "string", "description": "Referenced (parent) table (required)."},
        "ref_columns": {"type": "string", "description": "Referenced column(s) (required). Example: 'id'."},
        "schema": {"type": "string", "description": "Schema name (optional). Default: 'public'."},
        "constraint_name": {"type": "string", "description": "Constraint name (optional). Auto-generated if omitted."},
        "on_delete": {"type": "string", "description": "ON DELETE action (optional). Examples: 'CASCADE', 'SET NULL', 'RESTRICT', 'NO ACTION'."},
        "on_update": {"type": "string", "description": "ON UPDATE action (optional). Examples: 'CASCADE', 'SET NULL', 'RESTRICT'."}
      },
      "required": ["table", "columns", "ref_table", "ref_columns"]
    }
  },
  {
    "name": "drop_foreign_key",
    "description": "Drop a foreign key constraint by name. Use show_constraints to find constraint names.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "table": {"type": "string", "description": "Table name (required)."},
        "constraint": {"type": "string", "description": "Constraint name to drop (required). Use show_constraints to list names."},
        "schema": {"type": "string", "description": "Schema name (optional). Default: 'public'."},
        "cascade": {"type": "boolean", "description": "Drop dependent objects (optional). Default: false."}
      },
      "required": ["table", "constraint"]
    }
  },
  {
    "name": "add_unique_constraint",
    "description": "Add a UNIQUE constraint to one or more columns. Prevents duplicate values. Applies across all rows in the table.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "table": {"type": "string", "description": "Table name (required)."},
        "columns": {"type": "string", "description": "Column(s) for uniqueness (required). Comma-separated. Example: 'email' or 'org_id, name'."},
        "schema": {"type": "string", "description": "Schema name (optional). Default: 'public'."},
        "constraint_name": {"type": "string", "description": "Constraint name (optional). Auto-generated if omitted."}
      },
      "required": ["table", "columns"]
    }
  },
  {
    "name": "drop_constraint",
    "description": "Drop any table constraint (PRIMARY KEY, UNIQUE, CHECK, FOREIGN KEY) by name. Use show_constraints to find constraint names.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "table": {"type": "string", "description": "Table name (required)."},
        "constraint": {"type": "string", "description": "Constraint name to drop (required)."},
        "schema": {"type": "string", "description": "Schema name (optional). Default: 'public'."},
        "cascade": {"type": "boolean", "description": "Drop dependent objects (optional). Default: false."}
      },
      "required": ["table", "constraint"]
    }
  },
  {
    "name": "cancel_query",
    "description": "Cancel a running query by PID. Sends SIGINT to the backend process. Safer than terminate_connection - allows the query to rollback gracefully.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "pid": {"type": "integer", "description": "PID of the query to cancel (required). Use show_running_queries to find PIDs."}
      },
      "required": ["pid"]
    }
  },
  {
    "name": "terminate_connection",
    "description": "Terminate a database connection by PID. Disconnects the client. Use as last resort for hung or problematic connections. Less graceful than cancel_query.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "pid": {"type": "integer", "description": "PID of the connection to terminate (required). Use list_connections to find PIDs."}
      },
      "required": ["pid"]
    }
  },
  {
    "name": "show_blocked_queries",
    "description": "Show queries currently blocked waiting for locks held by other sessions. Pairs blocked queries with their blocker PID, user, and query. Useful for diagnosing contention.",
    "inputSchema": {
      "type": "object",
      "properties": {}
    }
  },
  {
    "name": "list_extensions",
    "description": "List all installed PostgreSQL extensions with version, schema, and description.",
    "inputSchema": {
      "type": "object",
      "properties": {}
    }
  },
  {
    "name": "create_extension",
    "description": "Install a PostgreSQL extension. Supports IF NOT EXISTS, schema specification, version pinning, and CASCADE for dependencies.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "name": {"type": "string", "description": "Extension name (required). Examples: 'pgvector', 'pg_textsearch', 'timescaledb', 'uuid-ossp'."},
        "schema": {"type": "string", "description": "Schema to install into (optional). Default: current schema."},
        "version": {"type": "string", "description": "Specific version (optional). Example: '0.7.4'."},
        "cascade": {"type": "boolean", "description": "Install dependencies (optional). Default: false."},
        "if_not_exists": {"type": "boolean", "description": "Skip if already installed (optional). Default: false."}
      },
      "required": ["name"]
    }
  },
  {
    "name": "drop_extension",
    "description": "Uninstall a PostgreSQL extension. Use CASCADE to drop dependent objects. Cannot drop extensions with required objects without CASCADE.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "name": {"type": "string", "description": "Extension name to drop (required)."},
        "if_exists": {"type": "boolean", "description": "Skip if not installed (optional). Default: false."},
        "cascade": {"type": "boolean", "description": "Drop dependent objects (optional). Default: false."}
      },
      "required": ["name"]
    }
  },
  {
    "name": "list_databases",
    "description": "List all databases with owner, encoding, collation, and description. Includes both regular and template databases.",
    "inputSchema": {
      "type": "object",
      "properties": {}
    }
  },
  {
    "name": "create_database",
    "description": "Create a new PostgreSQL database. Supports owner, encoding, and locale configuration. Cannot run inside a transaction block.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "name": {"type": "string", "description": "Database name (required). 1-255 characters."},
        "owner": {"type": "string", "description": "Database owner (optional). Default: current user."},
        "encoding": {"type": "string", "description": "Character encoding (optional). Example: 'UTF8'."},
        "locale": {"type": "string", "description": "Locale / LC_COLLATE (optional). Example: 'en_US.UTF-8'."}
      },
      "required": ["name"]
    }
  },
  {
    "name": "vacuum",
    "description": "Run VACUUM to reclaim storage and update visibility map. Supports options: FULL, FREEZE, VERBOSE. Less disruptive than VACUUM FULL but does not return disk space to OS.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "table": {"type": "string", "description": "Table name (optional). If omitted, vacuums entire database."},
        "schema": {"type": "string", "description": "Schema name (optional). Default: 'public'."},
        "full": {"type": "boolean", "description": "Run VACUUM FULL (optional). Default: false. Locks table exclusively."},
        "freeze": {"type": "boolean", "description": "Aggressively freeze tuples (optional). Default: false."},
        "verbose": {"type": "boolean", "description": "Show detailed progress (optional). Default: false."}
      },
      "required": []
    }
  },
  {
    "name": "vacuum_full",
    "description": "Run VACUUM FULL to reclaim disk space and compact tables. Acquires exclusive lock. Use during low-traffic periods. More aggressive than standard VACUUM.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "table": {"type": "string", "description": "Table name (optional). If omitted, processes entire database."},
        "schema": {"type": "string", "description": "Schema name (optional). Default: 'public'."},
        "analyze": {"type": "boolean", "description": "Update statistics after vacuum (optional). Default: false."},
        "freeze": {"type": "boolean", "description": "Aggressively freeze tuples (optional). Default: false."},
        "verbose": {"type": "boolean", "description": "Show detailed progress (optional). Default: false."}
      },
      "required": []
    }
  },
  {
    "name": "reindex_database",
    "description": "Rebuild all indexes in a database, schema, or specific table/index. Use CONCURRENTLY to avoid locking writes during reindex. Helps recover from index bloat and corruption.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "database": {"type": "string", "description": "Database name to reindex (required)."},
        "schema": {"type": "string", "description": "Schema name (optional). Scopes operation to schema."},
        "table": {"type": "string", "description": "Table name (optional). Scopes operation to table. Requires schema."},
        "index": {"type": "string", "description": "Specific index name (optional). Scopes operation to one index."},
        "concurrent": {"type": "boolean", "description": "Use CONCURRENTLY - no write lock (optional). Default: false."},
        "verbose": {"type": "boolean", "description": "Show detailed progress (optional). Default: false."}
      },
      "required": ["database"]
    }
  },
  {
    "name": "generate_create_table_ddl",
    "description": "Generate the CREATE TABLE DDL statement for an existing table. Useful for migrations, documentation, and recreating tables in other environments. Includes columns, types, defaults, nullability, and primary key.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "table": {"type": "string", "description": "Table name (required)."},
        "schema": {"type": "string", "description": "Schema name (optional). Default: 'public'."}
      },
      "required": ["table"]
    }
  },
  {
    "name": "generate_create_index_ddl",
    "description": "Generate CREATE INDEX DDL statements for all indexes on a table. Useful for migrating index definitions between environments.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "table": {"type": "string", "description": "Table name (required)."},
        "schema": {"type": "string", "description": "Schema name (optional). Default: 'public'."}
      },
      "required": ["table"]
    }
  },
  {
    "name": "table_dependencies",
    "description": "Show what database objects depend on a table and what the table depends on. Critical before DROP operations to understand impact. Shows views, foreign keys, materialized views referencing the table.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "table": {"type": "string", "description": "Table name (required)."},
        "schema": {"type": "string", "description": "Schema name (optional). Default: 'public'."}
      },
      "required": ["table"]
    }
  },
  {
    "name": "list_vector_columns",
    "description": "List all columns with the vector data type (pgvector extension). Shows schema, table, and column name for each vector column.",
    "inputSchema": {
      "type": "object",
      "properties": {}
    }
  },
  {
    "name": "vector_search",
    "description": "Perform vector similarity search using pgvector. Supports cosine (default), Euclidean (L2), and inner product distance. Returns results ordered by similarity. Requires pgvector extension.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "table": {"type": "string", "description": "Table name (required)."},
        "column": {"type": "string", "description": "Vector column name (required)."},
        "vector": {"type": "string", "description": "Query vector as JSON array string (required). Example: '[0.1,0.2,0.3,0.4]'."},
        "schema": {"type": "string", "description": "Schema name (optional). Default: 'public'."},
        "limit": {"type": "integer", "description": "Max results (optional). Default: 10. Max: 1000."},
        "select": {"type": "string", "description": "Columns to return (optional). Default: '*'. Example: 'id, title'."},
        "distance": {"type": "string", "description": "Distance metric (optional). Options: 'cosine' (default), 'l2'/'euclidean', 'inner'/'ip'."}
      },
      "required": ["table", "column", "vector"]
    }
  },
  {
    "name": "create_vector_index",
    "description": "Create an index on a vector column for fast similarity search. Supports HNSW (default) and IVFFlat index types. HNSW builds slower but has better recall. IVFFlat is faster to build with configurable lists.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "table": {"type": "string", "description": "Table name (required)."},
        "column": {"type": "string", "description": "Vector column name (required)."},
        "schema": {"type": "string", "description": "Schema name (optional). Default: 'public'."},
        "index_type": {"type": "string", "description": "Index type (optional). 'hnsw' (default) or 'ivfflat'."},
        "distance": {"type": "string", "description": "Distance operator (optional). 'cosine' (default), 'l2'/'euclidean', 'inner'/'ip'."},
        "lists": {"type": "integer", "description": "IVFFlat lists parameter (optional). Default: 100. Only used with ivfflat index_type."}
      },
      "required": ["table", "column"]
    }
  },
  {
    "name": "create_hypertable",
    "description": "Convert a regular PostgreSQL table into a TimescaleDB hypertable for time-series data. Requires the timescaledb extension. Partitioning is automatic based on time intervals.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "table": {"type": "string", "description": "Table name to convert (required)."},
        "time_column": {"type": "string", "description": "Time column name (required). Must be TIMESTAMPTZ, TIMESTAMP, or DATE."},
        "schema": {"type": "string", "description": "Schema name (optional). Default: 'public'."},
        "chunk_time_interval": {"type": "string", "description": "Chunk time interval as INTERVAL (optional). Example: '1 day', '7 days', '1 month'."}
      },
      "required": ["table", "time_column"]
    }
  },
  {
    "name": "show_hypertable_details",
    "description": "Show detailed information about a TimescaleDB hypertable. Returns dimensions, chunk target size, compression state, and tablespace configuration. Requires timescaledb extension.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "table": {"type": "string", "description": "Hypertable name (required)."},
        "schema": {"type": "string", "description": "Schema name (optional). Default: 'public'."}
      },
      "required": ["table"]
    }
  },
  {
    "name": "show_chunks",
    "description": "List all chunks of a TimescaleDB hypertable. Shows chunk names, time ranges, compression status, and disk sizes. Useful for monitoring data distribution and compression.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "table": {"type": "string", "description": "Hypertable name (required)."},
        "schema": {"type": "string", "description": "Schema name (optional). Default: 'public'."}
      },
      "required": ["table"]
    }
  },
  {
    "name": "add_retention_policy",
    "description": "Add a data retention policy to automatically drop outdated chunks from a TimescaleDB hypertable. Data older than the specified interval is deleted by a background job.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "table": {"type": "string", "description": "Hypertable name (required)."},
        "schema": {"type": "string", "description": "Schema name (optional). Default: 'public'."},
        "drop_after": {"type": "string", "description": "Retention interval (required). Example: '90 days', '6 months', '1 year'."}
      },
      "required": ["table", "drop_after"]
    }
  },
  {
    "name": "add_compression_policy",
    "description": "Add a compression policy to automatically compress chunks older than the specified interval. Reduces storage costs for historical time-series data. Requires timescaledb extension.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "table": {"type": "string", "description": "Hypertable name (required)."},
        "schema": {"type": "string", "description": "Schema name (optional). Default: 'public'."},
        "compress_after": {"type": "string", "description": "Age threshold for compression (required). Example: '7 days', '1 month'."}
      },
      "required": ["table", "compress_after"]
    }
  },
  {
    "name": "compress_chunk",
    "description": "Manually compress a specific chunk of a TimescaleDB hypertable. Useful for immediate compression of a chunk that meets the age threshold.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "chunk_name": {"type": "string", "description": "Chunk name to compress (required). Use show_chunks to find chunk names."},
        "chunk_schema": {"type": "string", "description": "Chunk schema (optional). Default: '_hyper'."}
      },
      "required": ["chunk_name"]
    }
  },
  {
    "name": "add_continuous_aggregate",
    "description": "Create a TimescaleDB continuous aggregate (materialized view) for real-time downsampling of time-series data. Automatically refreshes at the specified interval.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "name": {"type": "string", "description": "Continuous aggregate view name (required)."},
        "query": {"type": "string", "description": "SELECT query defining the aggregation (required). Example: 'SELECT time_bucket(''1 hour'', ts) AS bucket, AVG(temperature) FROM sensor_data GROUP BY bucket'."},
        "refresh_interval": {"type": "string", "description": "Auto-refresh interval (optional). Example: '1 hour'. If omitted, create without auto-refresh."}
      },
      "required": ["name", "query"]
    }
  },
  {
    "name": "list_bm25_indexes",
    "description": "List all BM25 full-text search indexes (pg_textsearch extension). Shows schema, table, index name, definition, and usage statistics.",
    "inputSchema": {
      "type": "object",
      "properties": {}
    }
  },
  {
    "name": "search_bm25",
    "description": "Execute a BM25 relevance-ranked full-text search query using the pg_textsearch extension. Returns results ordered by relevance score. Supports explicit index specification. Requires pg_textsearch extension and shared_preload_libraries.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "table": {"type": "string", "description": "Table to search (required)."},
        "text_column": {"type": "string", "description": "Text column to search against (required). Must have a BM25 index."},
        "query": {"type": "string", "description": "Search query text (required). Example: 'performance optimization'."},
        "schema": {"type": "string", "description": "Schema name (optional). Default: 'public'."},
        "index_name": {"type": "string", "description": "Explicit BM25 index name (optional). Required for partial indexes and PL/pgSQL compatibility."},
        "limit": {"type": "integer", "description": "Max results (optional). Default: 10. Max: 1000."},
        "select": {"type": "string", "description": "Columns to return (optional). Default: '*'. Example: 'id, title, created_at'."}
      },
      "required": ["table", "text_column", "query"]
    }
  },
  {
    "name": "create_bm25_index",
    "description": "Create a BM25 full-text search index on a text column using the pg_textsearch extension. Supports custom BM25 parameters (k1, b), text search configurations, expression indexes, and partial indexes.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "table": {"type": "string", "description": "Table name (required)."},
        "column": {"type": "string", "description": "Text column to index (required). Can be an expression for expression indexes."},
        "text_config": {"type": "string", "description": "PostgreSQL text search configuration (optional). Default: 'english'. Options: 'english', 'french', 'german', 'simple', etc."},
        "schema": {"type": "string", "description": "Schema name (optional). Default: 'public'."},
        "index_name": {"type": "string", "description": "Custom index name (optional). Auto-generated if omitted."},
        "k1": {"type": "number", "description": "Term frequency saturation parameter (optional). Default: 1.2. Range: 0.1-10.0."},
        "b": {"type": "number", "description": "Length normalization parameter (optional). Default: 0.75. Range: 0.0-1.0."},
        "concurrently": {"type": "boolean", "description": "Create without blocking writes (optional). Default: false."},
        "where": {"type": "string", "description": "Partial index WHERE clause (optional). Example: 'status = ''published'''."}
      },
      "required": ["table", "column"]
    }
  },
  {
    "name": "drop_bm25_index",
    "description": "Drop a BM25 full-text search index. Supports IF EXISTS and CONCURRENTLY options.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "index_name": {"type": "string", "description": "Index name to drop (required). Use list_bm25_indexes to find index names."},
        "schema": {"type": "string", "description": "Schema name (optional). Default: 'public'."},
        "if_exists": {"type": "boolean", "description": "Skip if index doesn't exist (optional). Default: false."},
        "concurrently": {"type": "boolean", "description": "Drop without blocking writes (optional). Default: false."}
      },
      "required": ["index_name"]
    }
  },
  {
    "name": "bm25_force_merge",
    "description": "Force-merge all BM25 index segments into one. Improves query performance after bulk inserts. Similar to Lucene's forceMerge(1). Best used after large batch loads, not during ongoing write traffic.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "index_name": {"type": "string", "description": "BM25 index name to merge (required)."}
      },
      "required": ["index_name"]
    }
  },
  {
    "name": "bm25_index_stats",
    "description": "Show internal statistics and structure of a BM25 index. Returns segment count, document counts, and index health information for debugging and performance analysis.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "index_name": {"type": "string", "description": "BM25 index name (required)."}
      },
      "required": ["index_name"]
    }
  },
  {
    "name": "import_from_url",
    "description": "Download a CSV file from a URL and import it into a PostgreSQL table using COPY FROM STDIN. Supports configurable delimiter, header row, and optional truncate before import. Ideal for loading data from S3, GitHub raw URLs, or any HTTP-accessible CSV.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "url": {"type": "string", "description": "URL of the CSV file to import (required). Supports HTTP/HTTPS."},
        "table": {"type": "string", "description": "Target table name (required)."},
        "schema": {"type": "string", "description": "Target schema (optional). Default: 'public'."},
        "delimiter": {"type": "string", "description": "CSV delimiter (optional). Default: ','."},
        "header": {"type": "boolean", "description": "CSV has header row (optional). Default: true."},
        "truncate": {"type": "boolean", "description": "Truncate table before import (optional). Default: false."},
        "columns": {"type": "string", "description": "Comma-separated column list for target columns (optional). Default: all columns."}
      },
      "required": ["url", "table"]
    }
  },
  {
    "name": "export_csv",
    "description": "Export a table or SELECT query result as CSV text using COPY TO STDOUT. Returns the full CSV content in the response. Safe for moderate-sized exports (up to 100,000 rows). Use 'table' for a full table export or 'query' for a custom SELECT.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "query": {"type": "string", "description": "SELECT query to export (optional, alternative to 'table'). Must be a SELECT statement."},
        "table": {"type": "string", "description": "Table name to export (optional, alternative to 'query')."},
        "schema": {"type": "string", "description": "Schema name (optional). Default: 'public'."},
        "header": {"type": "boolean", "description": "Include CSV header row (optional). Default: true."},
        "delimiter": {"type": "string", "description": "CSV delimiter (optional). Default: ','."},
        "limit": {"type": "number", "description": "Maximum rows to export (optional). Default: 10000, Max: 100000."}
      },
      "required": []
    }
  },
  {
    "name": "suggest_indexes",
    "description": "Analyze pg_stat_user_tables to find tables with high sequential scan counts and recommend new indexes. Examines table size, scan frequency, and existing indexes to prioritize suggestions. Read-only — no indexes are created.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "schema": {"type": "string", "description": "Schema to analyze (optional). Default: all user schemas."},
        "min_scan_threshold": {"type": "number", "description": "Minimum sequential scans to consider (optional). Default: 100."},
        "min_table_size_mb": {"type": "number", "description": "Minimum table size in MB (optional). Default: 10."}
      },
      "required": []
    }
  },
  {
    "name": "find_tables_without_pk",
    "description": "List all tables in user schemas that lack a primary key. Tables without a PK can cause performance issues (slow updates/deletes), replication problems, and ORM compatibility issues.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "schema": {"type": "string", "description": "Schema to check (optional). Default: all user schemas."}
      },
      "required": []
    }
  },
  {
    "name": "find_missing_fk_indexes",
    "description": "Find foreign key columns that lack an index. Unindexed FK columns cause row-level lock contention during UPDATE/DELETE on the parent table and slow down JOIN queries. Returns CREATE INDEX suggestions.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "schema": {"type": "string", "description": "Schema to check (optional). Default: all user schemas."}
      },
      "required": []
    }
  },
  {
    "name": "analyze_table_bloat",
    "description": "Estimate table bloat percentage using pg_stat_user_tables dead/live tuple ratios. Helps identify tables that need VACUUM or VACUUM FULL. Returns bloat percentage, dead/live tuple counts, and estimated bloat in bytes.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "schema": {"type": "string", "description": "Schema to analyze (optional). Default: all user schemas."},
        "threshold": {"type": "number", "description": "Minimum bloat percentage to include (optional). Default: 10."}
      },
      "required": []
    }
  },
  {
    "name": "clone_table_schema",
    "description": "Create a new table with the same structure as an existing table using CREATE TABLE ... (LIKE ... INCLUDING ...). Optionally copies indexes, defaults, and constraints. The new table starts empty.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "source_table": {"type": "string", "description": "Source table name (required)."},
        "new_table": {"type": "string", "description": "New table name (required)."},
        "source_schema": {"type": "string", "description": "Source schema (optional). Default: 'public'."},
        "new_schema": {"type": "string", "description": "Target schema (optional). Default: 'public'."},
        "include_indexes": {"type": "boolean", "description": "Copy indexes (optional). Default: true."},
        "include_defaults": {"type": "boolean", "description": "Copy column defaults (optional). Default: true."},
        "include_constraints": {"type": "boolean", "description": "Copy CHECK constraints (optional). Default: false."}
      },
      "required": ["source_table", "new_table"]
    }
  },
  {
    "name": "security_audit",
    "description": "Comprehensive security audit of the database. Reports superuser accounts, tables with PUBLIC access (world-readable/writable), and default privileges. Essential for compliance reviews and security hardening.",
    "inputSchema": {
      "type": "object",
      "properties": {},
      "required": []
    }
  },
  {
    "name": "audit_role_usage",
    "description": "List all database roles with their attributes (superuser, login, connection limits, expiry) and membership information. Use 'role' parameter to inspect a specific role.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "role": {"type": "string", "description": "Specific role name to inspect (optional). Default: all roles."}
      },
      "required": []
    }
  },
  {
    "name": "sample_data",
    "description": "Extract a random sample of rows from a table. Supports optional WHERE filter, custom ORDER BY, and column anonymization (emails → ****@domain, strings → f...t). Results are randomized by default for unbiased sampling.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "table": {"type": "string", "description": "Table name (required)."},
        "schema": {"type": "string", "description": "Schema name (optional). Default: 'public'."},
        "limit": {"type": "number", "description": "Maximum rows to return (optional). Default: 100, Max: 10000."},
        "where": {"type": "string", "description": "Optional WHERE clause (without the WHERE keyword). Example: 'created_at > NOW() - INTERVAL 7 days'."},
        "order_by": {"type": "string", "description": "Column to order by (optional). Default: RANDOM()."},
        "anonymize_columns": {"type": "array", "items": {"type": "string"}, "description": "Column names to anonymize (optional). Emails become ****@domain, strings become f...t."}
      },
      "required": ["table"]
    }
  }
]