PostgreSQL MCP Server that exposes PostgreSQL database functionality through MCP: Resources for table schemas and metadata, Tools for read-only SQL query execution, and Prompts for common data analysis tasks
The PostgreSQL MCP server defines 4 tools with acceptable naming and partial documentation. All tools follow verb-noun convention (list_tables, get_table_schema, execute_query, get_table_stats), which is strong. However, parameter descriptions are minimal or absent, output schemas are not formally documented, and error handling is generic. The server lacks pagination support for potentially large result sets, and descriptions do not explain when to use each tool vs. alternatives. Tool definitions are directly visible in the code, so no inference penalty applies. Average of 4 tools: (65+58+55+58)/4 = 58.5.
Execute a read-only SQL query and return results. Args: query: SQL query to execute (must be SELECT, WITH, or SHOW statement) Returns: Dictionary containing rows and metadata
Get the schema for a specific table. Args: table_name: Name of the table to describe Returns: Dictionary with table schema information
Get statistics for a table. Args: table_name: Name of the table to analyze Returns: Dictionary containing table statistics
List all tables in the database. Returns: Dictionary with list of tables and their types
Output schemas not formally documented. Tools return dicts with fields like 'tables', 'rows', 'columns', 'count', but no explicit schema definition (JSON Schema) is provided to guide LLMs on structure and downstream tool chaining.
Parameter 'query' in execute_query lacks format constraints and examples in description. Description states 'must be SELECT, WITH, or SHOW' but does not explain time limits, result row caps, or examples of valid queries. LLMs may pass overly complex or long-running queries.
No pagination support. All tools return entire result sets without limit, offset, or cursor parameters. Large tables (thousands of rows) will blow context windows. list_tables description does not state result limits.
Inferred effective spec: <=2025-11-25.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | F | 49 | <=2025-11-25 | v2 |
| 2026-03-09 | F | 0 | - | v1 |
Descriptions lack actionable guidance on tool selection and sequencing. No documentation explaining when to call list_tables first vs. get_table_schema, or how these tools compose into a workflow. LLMs must infer this from sparse descriptions.
Error handling is minimal and generic. execute_query returns a dict with 'error' key on invalid queries, but does not provide recovery guidance (e.g., 'Try starting with SELECT'). Exception handler logs but does not communicate actionable next steps to the agent.
No response field naming alignment with parameter names. Tool descriptions do not ensure that fields returned by one tool match parameter names of downstream tools. For example, list_tables returns 'table_name' as part of each row, but get_table_schema expects 'table_name' as a parameter, consistency is not guaranteed in documentation.
Sensitive operations (execute_query) accept arbitrary SQL. While input validation checks for SELECT/WITH/SHOW, no protection against SQL injection via table_name parameters in get_table_schema and get_table_stats. Code uses sql.Identifier (good), but this is not documented for the LLM.