An MCP server that enables natural language querying of PostgreSQL databases by introspecting schema and generating SQL queries using OpenAI's GPT-4o model
Single tool 'ask_question' has critical definition gaps. Tool name lacks action verb clarity (should be 'query_database' or 'execute_sql_from_question'). Description is adequate (97 chars) but input schema is severely malformed: parameter 'request' wraps an 'InferRequest' object containing 'messages' array, but the schema nesting is confusing and underdocumented. No output schema documented. No parameter descriptions for 'role' or 'content' fields. No error handling guidance. Tool performs LLM-based SQL generation (security risk) but lacks validation, injection prevention, or recovery patterns. Missing idempotency hints despite state-modifying database calls.
Accepts a natural language question, introspects the PostgreSQL database schema, generates a SQL query using GPT-4o, executes it, and returns the results
Tool name 'ask_question' lacks action verb. Should be 'query_database' or 'execute_sql_from_question' to signal intent clearly. Current name is vague and does not follow verb_noun convention.
Input schema is malformed and underdocumented. Parameter 'request' wraps InferRequest with nested 'messages' array, but no descriptions for 'role' or 'content' fields. LLM cannot infer what values are valid (e.g., is role always 'user'? what format for content?).
No output schema documented. Tool returns dict with 'result', 'status', or 'error' keys, but structure is not formally specified. LLM cannot plan downstream operations or extract fields reliably.
SQL generation via GPT-4o without input validation or injection prevention. Tool accepts arbitrary natural language, generates SQL, and executes it. No sanitization, no prepared statements visible, no rate limiting. High SQL injection risk.
Inferred effective spec: <=2025-11-25.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | F | 31 | <=2025-11-25 | v2 |
Error handling returns raw exception strings ('error': str(e)) with no recovery guidance. LLM cannot determine if error is retryable, user-fixable, or fatal. No actionable error messages.