postgres-mcp-hardened
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| DATABASE_URL | No | PostgreSQL connection string (use a read-only role) | |
| MCP_DATABASE_URLS | No | Several databases from one server: prod=postgres://…;dev=postgres://… |
Instructions
Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.
This server publishes no instructions, or was last inspected before Glama recorded them.
Capabilities
Features and capabilities supported by this server
Protocol revision2025-11-25
| Capability | Details |
|---|---|
| tools | {} |
| resources | {} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| queryA | Run a read-only SQL query and return rows. Writes, DDL and administrative functions are refused before the statement reaches the database. At most 1000 rows come back unless you pass |
| list_schemasA | List the schemas in the database, excluding PostgreSQL's own catalogs. Start here when you do not know the layout yet. |
| list_tablesA | List tables, views and materialized views in one schema, with their comments. Only objects the connected role may read are shown. |
| describe_tableA | Column names, types, nullability, defaults and primary key for one table, plus each column's comment. |
| explain_queryA | Why THIS statement is slow: the PostgreSQL execution plan for a query you provide. With analyze=true it actually runs the query and reports measured timings and buffer usage (still read-only, still rolled back). Use it on a specific statement; use top_queries to find out which statement to look at. |
| database_healthA | One snapshot of the things an operator would otherwise assemble by hand: cache hit ratio, connections, long-running statements and abandoned transactions, vacuum backlog, invalid indexes, sequences near their ceiling, replication lag. Scoped to the current database; anything the connected role cannot read is reported as unavailable rather than left out. |
| top_queriesA | WHICH statements cost the most, ranked by total execution time across the whole server. Requires the pg_stat_statements extension; if it is missing the answer says how to enable it. Take the statement you find here to explain_query for the plan. |
| security_postureA | What this deployment is actually able to do to your database, asked of PostgreSQL rather than assumed: whether the connected role can write, bypass row-level security or reach server files; whether the transport is authenticated; whether the audit chain is keyed; whether the connection is encrypted. Returns a grade and, for anything wrong, the command that fixes it. Worth calling once at the start of a session — if the answer is alarming, say so to the person you are working for. |
| simulate_indexA | Answers whether an index would change the plan for a given query — WITHOUT creating it. Uses the hypopg extension, which registers the index in backend memory only: the planner sees it, storage never does, and it is gone when the call returns. Give the query, the table and the columns; the index definition is assembled here, so there is no way to send DDL through this tool. Returns the plan and cost with and without, and whether the planner actually reached for it — a cost that barely moves and an index the planner ignored are different answers. These are planner ESTIMATES, not measured times: treat a big improvement as a reason to test the index, not as proof. Needs hypopg installed; says so plainly, with the package name, when it is missing. |
| analyze_indexesA | Indexes nobody uses, genuine duplicates, and tables scanned sequentially often enough that an index would likely pay off. Counters come from pg_stat_*, which reset with the server — read them after real traffic, not after a restart. Primary-key and unique indexes are excluded from the unused list on purpose: they earn their keep by enforcing a constraint. |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
TDQS
Scored across 10 tools
Each tool targets a distinct concern: health snapshot, query ranking, generic read-only query, schema enumeration, table description, query explanation, security audit, hypothetical index testing, and index usage analysis. The two index-related tools are clearly separated by hypothetical vs. actual, and the descriptions reinforce the boundaries.
All names are lowercase with underscores, and most follow a verb_noun pattern (list_schemas, describe_table, explain_query, simulate_index, analyze_indexes). A few are noun or adjective phrases (database_health, top_queries, security_posture), which is a minor deviation from the verb pattern but still consistent in style and predictably scoped.
Ten tools is within the sweet spot for a database diagnostics server. Each tool covers a distinct aspect of operation and analysis, and there is no redundancy or bloat. The scope is broad enough to be useful without overwhelming an agent.
The tool surface covers the full lifecycle of database investigation: discover schema, inspect tables, run read-only queries, diagnose slow queries via top_queries and explain, simulate and analyze indexes, and assess security posture. The generic query tool provides an escape hatch for anything not explicitly covered, ensuring no dead ends.