MCP server for multi-database PostgreSQL analytics. Ask your databases questions in natural language.
dbecho demonstrates solid tool design with 14 well-named, read-only database analytics tools. All tools have descriptions (avg 180 chars, within 10-1024 baseline) and input schemas with typed parameters. Naming follows verb_noun convention (list_, schema, query, describe, find, sample, analyze, anomalies, trend, compare, erd, explain, summary). However, several parameter descriptions lack actionable detail (e.g., 'where' clause format hints, enum constraints for 'bucket' and 'aggregation'). Output schemas are not explicitly documented in tool definitions, LLMs must infer structure from descriptions. Error handling is minimal; tools return generic error strings rather than recovery guidance. No tool annotations (readOnlyHint, idempotentHint) despite all being read-only. Composition is strong: tools chain well (list_databases → schema → query), and results include necessary IDs for downstream calls.
Profile a table: row count, column stats (nulls, cardinality, min/max for numerics/dates). Refused on tables above max_profile_rows (default 5M) to prevent expensive full-table scans. Use query for targeted analysis on large tables.
Find data quality issues: NULL rates, cardinality anomalies, outliers in numeric/date columns. Refused on tables above max_profile_rows (default 5M). Use query for targeted checks on large tables.
Compare a table across multiple databases: row counts, column counts, and schema differences. Useful for spotting drift between environments (dev/staging/prod). Limited to 20 databases per call.
Describe a single table: columns, types, primary key, indexes, row estimate, size. Much cheaper than schema when you only need one table. Works on a partition child too.
Generate an entity-relationship diagram (ERD) for a database in Mermaid format. Shows tables, columns, primary keys, and foreign key relationships. Partitioned tables are marked [partitioned]. Mermaid can be rendered by most markdown viewers and Claude.
Output schemas not documented. Tool descriptions explain what is returned (e.g., 'columns, rows, row_count, truncated' for query), but no formal schema definitions are visible in tool registration. LLMs must infer structure from prose, risking misinterpretation of nested fields and pagination.
Parameter constraints not formalized as enums. 'bucket' (hour/day/week/month/quarter/year) and 'aggregation' (sum/avg/min/max/count) are described as free-form strings. Should be enum types to prevent LLM hallucination of invalid values like 'decade' or 'median'.
Error handling lacks recovery guidance. Tools return generic strings like 'Schema error: {e}' or 'Invalid input' without actionable next steps. Should categorize errors (retryable, user-fixable, fatal) and suggest alternatives (e.g., 'Database not found. Available: prod, staging, dev').
Inferred effective spec: <=2025-11-25.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 64 | <=2025-11-25 | v2 |
Explain a query plan without executing it (or with ANALYZE to see actual costs). Use to preview query cost before running it on a large table. Only SELECT, WITH, EXPLAIN, and SHOW queries are allowed.
Search for tables and columns by name across all databases. Use % and _ as SQL LIKE wildcards (% = any chars, _ = one char). Case-insensitive. Returns up to 100 matches per kind per database.
Check connectivity and basic info for all configured databases.
List all configured PostgreSQL databases with their descriptions.
Execute a read-only SQL query on a database and return the results. Only SELECT, WITH, EXPLAIN, and SHOW queries are allowed.
Preview rows from a table with optional filtering and column selection. Useful for understanding data shape before writing complex queries. Row limit is configurable (default 500); use query for larger result sets.
Get the full schema of a database: tables, columns, types, primary keys, row counts, and sizes. Row counts are PostgreSQL planner estimates (0 for never-analyzed tables); use analyze or query for exact counts. Partitioned tables are listed once as the parent, marked [partitioned], with rows and size summed across all partitions; query the parent and let PostgreSQL prune.
Quick overview of all databases: row counts, table counts, and total sizes. Useful for getting a bird's-eye view before diving into specific databases.
Analyze time series: group a numeric column by time bucket and aggregate. Supports date/timestamp columns and various time buckets (hour, day, week, month, quarter, year). Useful for spotting trends and anomalies over time.
No tool annotations despite all tools being read-only. FastMCP supports readOnlyHint, idempotentHint, and destructiveHint. Adding readOnlyHint=true to all 14 tools signals to agents that these are safe to call without side effects.
Parameter descriptions lack format hints. 'where' clause in sample/trend accepts SQL WHERE syntax but description does not specify 'without the WHERE keyword' or provide an example. 'format' in query mentions 'table' and 'json' but does not explain output structure for each.