Skip to main content
Glama
YawLabs

@yawlabs/postgres-mcp

by YawLabs

Recommend indexes for a workload

pg_index_advisor
Read-onlyIdempotent

Recommends PostgreSQL indexes that measurably cut estimated query cost. Analyzes your SQL workload or top pg_stat_statements queries and returns only cost-effective index candidates.

Instructions

Recommend indexes for a workload, and prove each one pays for itself before recommending it. Give it statements (the SQL you care about) or let it take the top N from pg_stat_statements; it plans each statement, generates candidate indexes, costs them with HypoPG hypothetical indexes, and returns only the ones that measurably cut estimated cost. How candidates are generated, and the honest limit: this tool has NO SQL parser and does not read your SQL text. It EXPLAINs each statement and harvests the columns the PLANNER reports as filters, join keys, and sort keys, then intersects those tokens with the real column list from pg_attribute -- so a candidate can never name a column that does not exist. The extraction is deliberately loose (a token matching a real column name on a different table can slip through); HypoPG is the arbiter, and anything that does not lower cost is discarded. Column ORDER within each candidate is equality columns first (most selective first, from pg_stats), then at most one range column, then sort columns. The search is greedy and BOUNDED. Each accepted index stays in place while the rest are re-costed on top of it, so later picks account for what earlier ones already fixed. max_candidates caps how many candidates are considered and max_explains caps total EXPLAIN round trips; when a cap stops the search early, budget_exhausted is true and the result is a truncated search, not a converged one. PostgreSQL 18 note, and it reverses a rule you have probably internalized: PG18 added B-tree SKIP SCAN, so a multi-column index whose LEADING column the query never constrains CAN now be used. The classic 'leading column never filtered means the index is useless' heuristic is wrong on PG18+. This tool gates that prune on the server version -- on PG18+ such candidates are kept and costed (skip_scan_available: true, and an accepted one carries requires_skip_scan), below PG18 they are pruned as unusable and counted in candidates_pruned_leading_column. Requires the HypoPG extension (CREATE EXTENSION hypopg;). Hypothetical indexes are session-scoped and are reset before the call returns, on the success and the failure path alike, so they never touch disk and never leak into a later query plan. Statements are only ever EXPLAINed, never executed, inside a BEGIN READ ONLY transaction. Costs are PLANNER ESTIMATES, not measurements: they are the right way to compare two plans for the same statement and the wrong way to predict wall-clock time. They are weighted by calls when the workload came from pg_stat_statements, so a query run a million times outranks an identical one run twice. Validate a recommendation with pg_explain before creating it, and create it with CONCURRENTLY in production (create_statement_concurrently).

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
limitNoHow many statements to pull from pg_stat_statements. Ignored when `statements` is given.
schemaNoOnly recommend indexes on tables in this schema. Candidates elsewhere are dropped.
statementsNoThe workload to optimize. When omitted, the top `limit` statements from pg_stat_statements are used instead (and weighted by their call counts).
max_explainsNoCap on EXPLAIN round trips spent searching (baseline plans are not counted). The search stops when the next candidate would exceed it and reports `budget_exhausted: true`.
max_candidatesNoCap on candidate indexes considered. Candidates are ranked by table sequential-scan count first.
min_improvementNoFraction of total weighted workload cost an index must remove to be accepted (0.1 = 10%). Relative rather than absolute so it means the same thing on a small and a large database.
max_index_columnsNoWidest candidate index to consider. Every narrower prefix is considered too.
max_recommendationsNoStop after this many accepted indexes, even if more would still help.

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
_warningsNo
statementsYesThe workload as analyzed, in the order `helps_statements.statement` indexes into.
explains_usedYesEXPLAIN round trips spent searching, excluding baseline plans.
explain_budgetYes
recommendationsYes
budget_exhaustedYesTrue when `max_explains` stopped the search before it converged.
final_workload_costYesWeighted total after applying every recommendation.
skip_scan_availableYesTrue on PostgreSQL 18+, where B-tree skip scan exists.
candidates_consideredYes
baseline_workload_costYesWeighted total estimated cost before any recommendation.
candidates_pruned_leading_columnYesMulti-column candidates dropped by the pre-PG18 leading-column rule. Always 0 on PG18+.
Install Server

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Even though readOnlyHint/openWorldHint/idempotentHint/destructiveHint already cover safety, the description adds substantial beyond-annotation behavior: no SQL parser, EXPLAIN-only execution inside BEGIN READ ONLY, session-scoped HypoPG reset on success and failure, greedy bounded search with budget_exhausted, PG18 skip-scan handling, and planner-estimate caveats. Nothing contradicts the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is long but every block earns its place, covering generation, pruning, caps, version-specific behavior, side effects, and cost interpretation. The core purpose and proof requirement are front-loaded, followed by the most decision-critical caveats.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity and the existence of a rich output schema, the description covers all operational essentials: the honest no-parser limit, HypoPG requirement and cleanup, read-only safety, bounded search semantics, PG18 version reversal, and the correct interpretation of costs. No major decision-relevant context is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema already describes all 8 parameters at 100% coverage, setting a baseline of 3. The description adds meaningful interplay context: statements vs limit choice, max_candidates/max_explains as stopping caps that produce budget_exhausted, and call-count weighting, so it moves above baseline.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The opening line names a specific verb and resource — 'Recommend indexes for a workload' — and adds a concrete behavioral promise: each index must prove it pays for itself. This clearly distinguishes pg_index_advisor from siblings like pg_advisor, pg_explain, and pg_unused_indexes.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explains the two input modes (statements vs pg_stat_statements), states the HypoPG dependency, and tells the agent to validate with pg_explain and create with CONCURRENTLY. It does not explicitly say 'use this when...' or name when not to use it, but the context is clear enough to route a caller correctly.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/YawLabs/postgres-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server