PostgreSQL MCP server has 2 tools with basic schemas and descriptions. Tool naming follows verb_noun pattern but descriptions lack LLM-optimization details. Input schemas are present but parameter descriptions are minimal. No output schema documentation. Error handling exists but lacks recovery guidance. This is a minimal implementation that falls below production baseline for agent tooling.
Add output schema documentation for both tools. Specify: pg_query returns [{column_name: value, ...}, ...] array of row objects; pg_schema_info returns {tables: [{name, schema, columns: [{name, type, nullable, ...}], constraints: [...]}, ...]}. Include example JSON.
Expand tool descriptions to 150-250 chars. For pg_query: 'Execute arbitrary PostgreSQL queries for data retrieval, analysis, or modification. Use schema_info first to explore structure. SELECT queries are safe to retry; writes are not. Set unsafe=true for DDL/DML, otherwise DROP/DELETE/UPDATE are blocked.' For pg_schema_info: 'Discover database structure: table names, columns, types, primary keys, and constraints. Call before querying unknown tables. Returns all tables if table parameter is empty; provide table name for details only.'
Add explicit format/constraint documentation for parameters. For query: 'Standard PostgreSQL SQL. DDL (CREATE, ALTER, DROP) and DML (INSERT, UPDATE, DELETE) require unsafe=true. Must be syntactically valid.' For table: 'Table name (e.g., users, public.orders). Case-sensitive. Leave empty to list all tables.'
Implement pagination for query results. Add optional limit (default 50, max 1000) and offset (default 0) parameters. Update description: 'Large result sets are capped at limit rows. Use offset to fetch additional rows. If result count == limit, more rows exist; increment offset and retry.'
Document idempotency constraints explicitly. Add to pg_query description: 'WARNING: SELECT queries are idempotent and safe to retry. INSERT/UPDATE/DELETE/CREATE queries are NOT idempotent, retrying causes duplicate side effects. Use transactions or application-level deduplication for retry safety.'
'unsafe' parameter is boolean with no enum/constraint, leaves safety semantics ambiguous
pg_query
Enhance error messages with recovery guidance. For safety violations: 'Potentially unsafe query: contains DROP/DELETE/UPDATE/ALTER. Set unsafe=true to permit, or rewrite with safer SELECT. Example safe query: SELECT * FROM users WHERE id = $1;'. For execution errors: '[Error Type] at line N: [error details]. Invalid syntax example: [show what was invalid]. Did you mean: [suggest fix]?'
Add an enum-like constraint or description for the unsafe parameter: 'Boolean flag (true/false). true = permit DDL and DML (dangerous); false (default) = permit SELECT only. Use with caution.'
Consider adding a 'dry_run' parameter to pg_query for write operations: 'Boolean flag (true/false). If true, wrap query in transaction and ROLLBACK without committing changes. Useful for previewing results of destructive queries before executing.'
Add tool annotations for destructiveness. pg_query should have destructiveHint=true (or mark certain queries as destructive); pg_schema_info should have readOnlyHint=true. Enables client UI warnings.
Document dependency hints in descriptions. E.g., pg_query: 'If you only have a table name but not column names, call pg_schema_info first to explore structure.' pg_schema_info: 'Call this before writing queries to unfamiliar tables to avoid syntax errors.'
Add validation logic to reject obviously invalid SQL (e.g., multiple statements in one call, non-SELECT queries when unsafe=false) with clear error messages stating the exact constraint violated and how to fix it.