mcp-postgres 1.3.1

High-performance MCP server for PostgreSQL with CPU-aware connection pooling and optimized buffers
Documentation
[
  {
    "name": "list_tables",
    "description": "List all user-defined tables in the database with schema, name, and table type. Use this to discover available tables, understand the database structure, and identify which tables are available for querying or modification. Returns a list of tables (BASE TABLE, TEMPORARY, etc.) excluding system tables. Useful for schema exploration and data modeling.",
    "inputSchema": {
      "type": "object",
      "properties": {}
    }
  },
  {
    "name": "describe_table",
    "description": "Get detailed column information for a specific table including column names, data types, nullability, default values, and column order. Essential for understanding table structure before querying or modifying data. Shows constraints, triggers, and column descriptions. Use this to explore unfamiliar tables or verify schema assumptions.",
    "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": "execute_query",
    "description": "Execute a SELECT query and retrieve data. Returns result rows as arrays with column values. Supports all SELECT operations: filtering, aggregation, joins, subqueries, window functions, CTEs. Use for data retrieval, analysis, and reporting. Maximum query execution time enforced to prevent runaway queries.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "sql": {
          "type": "string",
          "description": "SELECT SQL query to execute (required). Max 10,000 characters. Examples: 'SELECT * FROM users LIMIT 10', 'SELECT COUNT(*) as count FROM orders WHERE status = ''shipped''', 'SELECT u.name, COUNT(o.id) FROM users u LEFT JOIN orders o ON u.id = o.user_id GROUP BY u.id'. Must be a SELECT query only."
        }
      },
      "required": ["sql"]
    }
  },
  {
    "name": "execute_insert",
    "description": "Execute an INSERT statement to add new records to a table. Returns the number of rows affected and optionally inserted IDs if RETURNING clause is used. Supports single row, multi-row, and SELECT-based inserts. Useful for adding new data, bulk imports, and data migrations. Rows are returned in the order inserted.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "sql": {
          "type": "string",
          "description": "INSERT SQL statement (required). Max 10,000 characters. Examples: 'INSERT INTO users (email, name) VALUES (''user@example.com'', ''John'')', 'INSERT INTO users (email, name) VALUES (''a@test.com'', ''A''), (''b@test.com'', ''B'') RETURNING id', 'INSERT INTO archive SELECT * FROM temp_table'. Use RETURNING clause to get inserted IDs or values."
        }
      },
      "required": ["sql"]
    }
  },
  {
    "name": "execute_update",
    "description": "Execute an UPDATE statement to modify existing records. Returns the number of rows affected. Supports conditional updates with WHERE clause, computed values, and RETURNING clause for verification. Essential for data corrections, status changes, and bulk updates. Consider using RETURNING to verify the changes.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "sql": {
          "type": "string",
          "description": "UPDATE SQL statement with WHERE clause for safety (required). Max 10,000 characters. Examples: 'UPDATE users SET status = ''active'' WHERE created_at > now() - interval ''7 days''', 'UPDATE products SET price = price * 1.1 WHERE category_id = 5 RETURNING id, price', 'UPDATE orders SET shipped_at = now() WHERE status = ''ready'''. ALWAYS include WHERE clause to prevent accidental updates."
        }
      },
      "required": ["sql"]
    }
  },
  {
    "name": "execute_delete",
    "description": "Execute a DELETE statement to remove records from a table. Returns the number of rows deleted. Always requires careful WHERE clauses to prevent accidental data loss. Consider backing up or using soft-delete (UPDATE status) for critical data. RETURNING clause shows which rows were deleted.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "sql": {
          "type": "string",
          "description": "DELETE SQL statement with WHERE clause (required). Max 10,000 characters. Examples: 'DELETE FROM audit_logs WHERE created_at < now() - interval ''90 days''', 'DELETE FROM temp_uploads WHERE status = ''failed'' RETURNING id, filename'. ALWAYS include a WHERE clause - deleting without one removes all rows. Use RETURNING to verify what was deleted."
        }
      },
      "required": ["sql"]
    }
  },
  {
    "name": "batch_insert",
    "description": "High-performance multi-row insert optimized for speed with synchronous_commit temporarily disabled. Insert up to 1,000 rows in a single operation. Much faster than individual INSERT statements for bulk loads. Returns rows affected count and optionally inserted IDs via RETURNING. Perfect for importing CSV data, test data loading, and bulk operations.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "table": {
          "type": "string",
          "description": "Target table name (required). Example: 'users', 'products', 'orders'. Case-insensitive. Must exist and have INSERT permissions."
        },
        "columns": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "Column names in order matching the row data (required). Example: ['email', 'name', 'created_at']. Column count must match row data length. Order matters - first column in array corresponds to first value in each row."
        },
        "rows": {
          "type": "array",
          "items": {
            "type": "array"
          },
          "description": "Array of rows to insert (required). Max 1,000 rows per call. Each row is an array of values matching columns order. Example: [['user1@test.com', 'User 1', '2026-01-01'], ['user2@test.com', 'User 2', '2026-01-02']]. NULL values supported as null."
        },
        "returning": {
          "type": "string",
          "description": "Optional: Column to return after insert. Example: 'id' returns inserted IDs, 'id, email' returns multiple columns. Useful for getting auto-generated IDs. Omit if not needed."
        }
      },
      "required": ["table", "columns", "rows"]
    }
  },
  {
    "name": "batch_insert_copy",
    "description": "Ultra-high-performance bulk insert using PostgreSQL's COPY protocol. Optimized for massive imports (10K+ rows). Uses automatic batching with configurable batch size. Returns total rows affected and batch count. Perfect for data warehouse loads, ETL operations, and large-scale migrations. Much faster than batch_insert for very large datasets.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "table": {
          "type": "string",
          "description": "Target table name (required). Example: 'users', 'events', 'transactions'. Case-insensitive. Should be empty or recently truncated for best performance."
        },
        "columns": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "Column names in order matching rows data (required). Example: ['id', 'event_type', 'timestamp', 'value']. All columns must be in the target table."
        },
        "rows": {
          "type": "array",
          "items": {
            "type": "array"
          },
          "description": "Array of rows as arrays of values (required). Can be very large (10K+, 100K+). Each row must have same number of values as columns. NULL values represented as null in JSON."
        },
        "batch_size": {
          "type": "integer",
          "description": "Rows per INSERT batch statement (optional, default: 1,000). Range: 100-5,000. Larger batches = faster but uses more memory. For 100K+ rows, use 1,000-2,000. For small inserts, can use larger values up to 5,000."
        }
      },
      "required": ["table", "columns", "rows"]
    }
  },
  {
    "name": "explain_query",
    "description": "Analyze query execution plans to understand performance characteristics. Shows how PostgreSQL will execute a SELECT query including sequential vs index scans, join types, and estimated rows. ANALYZE option executes the query and shows actual execution metrics. Use to identify missing indexes, slow joins, or inefficient query plans. Output format can be JSON (machine readable) or text (human readable).",
    "inputSchema": {
      "type": "object",
      "properties": {
        "sql": {
          "type": "string",
          "description": "SELECT query to explain (required). Example: 'SELECT u.id, u.email, 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 a SELECT query."
        },
        "analyze": {
          "type": "boolean",
          "description": "Execute query and show actual metrics (optional, default: false). Set to true to see real execution time, actual rows, and buffer stats. WARNING: This executes the query - avoid on slow queries. Use false for planning without execution."
        },
        "buffers": {
          "type": "boolean",
          "description": "Include buffer usage statistics (optional, default: false). Requires analyze=true. Shows shared_buffers hits/misses and I/O stats. Useful for diagnosing cache efficiency and disk I/O bottlenecks."
        },
        "format": {
          "type": "string",
          "enum": ["json", "text", "xml", "yaml"],
          "description": "Output format (optional, default: 'json'). 'json' = machine-readable, structured; 'text' = human-readable plain text (best for reading); 'xml' = structured markup; 'yaml' = human-readable structured. Recommend 'json' for parsing, 'text' for visual inspection."
        }
      },
      "required": ["sql"]
    }
  },
  {
    "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, and tables with excessive sequential scans. Excellent for spotting performance issues, identifying optimization opportunities, and monitoring overall database wellness. Runs multiple diagnostics and returns consolidated health status.",
    "inputSchema": {
      "type": "object",
      "properties": {}
    }
  },
  {
    "name": "list_unused_indexes",
    "description": "Identify indexes that have never been used (zero index scans) or are not helping with performance. These indexes consume disk space, slow down writes, and should be considered for removal. Returns index metadata including size estimates. Useful for cleanup and performance tuning. Review before removing to ensure they're truly unused (consider index-only scans).",
    "inputSchema": {
      "type": "object",
      "properties": {}
    }
  },
  {
    "name": "list_duplicate_indexes",
    "description": "Find potentially redundant or duplicate indexes that overlap in functionality. Duplicate indexes waste storage and slow down DML operations without benefiting queries. Shows which indexes are candidates for consolidation or removal. Useful for index optimization and cleanup after schema changes or migrations.",
    "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, and estimated time remaining. Use to track maintenance operations and identify long-running vacuum processes that might impact performance.",
    "inputSchema": {
      "type": "object",
      "properties": {}
    }
  },
  {
    "name": "get_object_details",
    "description": "Get comprehensive information about a specific table including: all columns with types, primary key, foreign keys, all indexes with definitions, constraints, table size estimates, row counts, description/comments. Use for thorough schema exploration, dependency mapping, and understanding table relationships. Returns everything needed to understand a table's role in the database.",
    "inputSchema": {
      "type": "object",
      "properties": {
        "table": {
          "type": "string",
          "description": "Table name to get details for (required). Example: 'users', 'orders', 'products'. Case-insensitive. Returns all columns, indexes, constraints, FKs, and metadata."
        },
        "schema": {
          "type": "string",
          "description": "Schema name containing the table (optional, default: 'public'). Example: 'public', 'staging', 'archive'. Use 'schema.table' format in table parameter to override. Specify if table exists in non-public schema."
        }
      },
      "required": ["table"]
    }
  },
  {
    "name": "list_indexes",
    "description": "List all indexes in the database with their definitions, associated tables, columns, and types (unique, partial, expression, etc.). Use for index inventory, migration planning, and understanding database indexing strategy. Shows CREATE INDEX statements that can be copied for replication.",
    "inputSchema": {
      "type": "object",
      "properties": {}
    }
  },
  {
    "name": "list_schemas",
    "description": "List all non-system schemas in the database with their owners and descriptions. Shows the organizational structure of database objects. Useful for understanding multi-schema setups, permissions, and logical data organization. Excludes system schemas like pg_catalog and information_schema.",
    "inputSchema": {
      "type": "object",
      "properties": {}
    }
  },
  {
    "name": "show_constraints",
    "description": "List all table constraints across the entire database including PRIMARY KEY, FOREIGN KEY, UNIQUE, CHECK, and NOT NULL constraints. Shows constraint definitions and which tables/columns are affected. Use for understanding data integrity rules, dependency chains, and constraint-driven optimization opportunities.",
    "inputSchema": {
      "type": "object",
      "properties": {}
    }
  },
  {
    "name": "list_database_privileges",
    "description": "List database-level access control lists (ACLs) and permissions for all non-template databases. Shows which users/roles have which privileges on each database (CONNECT, CREATE, TEMPORARY, etc.). Use for auditing access control, understanding permission structure, and verifying security policies.",
    "inputSchema": {
      "type": "object",
      "properties": {}
    }
  },
  {
    "name": "list_users",
    "description": "List all database users and roles with their attributes: superuser status, can create databases, can create roles, can login, connection limits, and validity expiration dates. Use for user administration auditing, understanding team access levels, and identifying unused or expired accounts.",
    "inputSchema": {
      "type": "object",
      "properties": {}
    }
  },
  {
    "name": "list_role_memberships",
    "description": "Show role membership hierarchy - which users belong to which roles and who has admin grant options. Useful for understanding permission inheritance, group membership structure, and organizational access patterns. Essential for permission auditing and understanding delegation levels.",
    "inputSchema": {
      "type": "object",
      "properties": {}
    }
  },
  {
    "name": "get_cache_hit_ratio",
    "description": "Get buffer cache hit ratio metrics from pg_stat_user_tables and pg_stat_user_indexes. Shows what percentage of data is being read from cache vs disk. High ratio (>95%) indicates efficient buffering. Low ratio suggests missing indexes, insufficient shared_buffers setting, or cold cache. Use to diagnose I/O performance issues.",
    "inputSchema": {
      "type": "object",
      "properties": {}
    }
  },
  {
    "name": "get_pg_stat_statements",
    "description": "Get top 50 slowest queries from pg_stat_statements extension ranked by total execution time. Shows query text, call count, mean time, max time, and total time. Essential for identifying performance bottlenecks and optimization targets. Requires pg_stat_statements extension to be installed and enabled. Use after enabling statistics for a representative period.",
    "inputSchema": {
      "type": "object",
      "properties": {}
    }
  },
  {
    "name": "get_setting",
    "description": "Retrieve a specific PostgreSQL configuration setting with full metadata: current value, unit (bytes/seconds/etc), description, context (when it can be changed), and default value. Use to inspect any configuration parameter (e.g., max_connections, shared_buffers, work_mem). 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' (max concurrent connections), 'shared_buffers' (memory for caching), 'work_mem' (memory per operation), 'effective_cache_size' (total available cache), 'random_page_cost' (cost model), 'maintenance_work_mem' (VACUUM/CREATE INDEX memory). Case-insensitive. Returns value, unit, description, and context."
        }
      },
      "required": ["setting_name"]
    }
  },
  {
    "name": "show_current_user",
    "description": "Show information about the current database connection: authenticated user, current database, PostgreSQL version with platform details, and system info. Use to verify connection identity, check PostgreSQL version compatibility, and understand session context. Helpful for debugging permission issues or verifying server configuration.",
    "inputSchema": {
      "type": "object",
      "properties": {}
    }
  },
  {
    "name": "show_session_info",
    "description": "Show current session connection details: current user, database, client IP address and port, server address and port, and application name. Useful for debugging connection issues, understanding session context in multi-client scenarios, and auditing who is connected where.",
    "inputSchema": {
      "type": "object",
      "properties": {}
    }
  }
]