MCP Universal Database Client - A Model Context Protocol server for connecting to and querying multiple databases (PostgreSQL, MySQL, SQLite) with support for read-only and destructive SQL operations.
Server has 6 tools with clear names and documented schemas, but descriptions lack depth and error handling is minimal. Tool names follow verb_noun convention well (connect_database, list_connections, query_read, query_write), making intent clear. Input schemas are present and properly typed using Zod, with enum constraints for dialect selection. However, descriptions are generic and don't guide LLM selection or explain when to use each tool vs alternatives. Parameter descriptions exist but are minimal (e.g., 'The connection ID' lacks context on what form it takes or whether names are accepted). Output structure is discussed in code but not formally documented for LLM visibility. Error responses are present but generic, lacking actionable recovery guidance. Security posture is reasonable (no credentials in params) but lacks explicit permission checks and audit logging.
Connect to a database using connection string
Disconnect all active database connections
Disconnect from a database using connection ID
List all active database connections
Run SELECT and other read-only SQL queries on the connected database. This tool only accepts non-destructive queries (SELECT, SHOW, DESCRIBE, EXPLAIN).
Run INSERT, UPDATE, DELETE and other destructive SQL queries on the connected database. Use with caution as this can modify data.
Output schemas not documented. Tools return text content but no structured schema is declared for LLM visibility into response fields (e.g., result rows, affected row count, error details). LLM cannot plan downstream operations without knowing response structure.
list_connections and disconnect_all have no input schema declared. These tools accept empty input but do not explicitly register an empty schema object, making it ambiguous whether they accept parameters.
Descriptions are generic and under 100 chars. Tool descriptions (e.g., 'List all active database connections', 'Disconnect from a database using connection ID') do not guide LLM selection or explain when to use each tool vs alternatives. Baseline for A+ tools is 150-250 chars with context on usage.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | C | 64 | 2026-07-28+ | v2 |
| 2026-03-09 | F | 44 | - | v1 |
Parameter descriptions lack constraint guidance. 'The connection ID' does not specify format, whether names are accepted, or how to obtain one. Baseline: descriptions should include format/constraint rules inline, e.g., 'The connection ID or name (created via connect_database)'.
Error handling lacks actionable recovery guidance. Errors are caught and returned via makeError() but do not categorize failures (retryable vs user-fixable vs fatal) or suggest next steps.
No pagination or result limits on query_read/query_write. If a SELECT returns 10,000 rows, all are serialized to LLM context, potentially exhausting token budget. No offset/limit parameters or documentation of a hard cap on results.
No confirmation or dry-run for destructive operations. query_write modifies data but offers no undo capability, confirmation step, or dry-run mode. Agents may execute DELETE/UPDATE accidentally.
No audit logging or permission gates. Tools do not log who executed what query, timestamp, or verify user/agent permissions before executing. Destructive operations bypass all authorization checks.
SQL injection vulnerability. analyzeQueryType() uses a simple parser but does not validate or sanitize query input. Malicious queries could bypass read-only enforcement or inject commands.