Return one partitioned table with every partition: its bound expression verbatim, whether it is the DEFAULT, whether it is itself partitioned, estimated rows and size (both null, not 0, for a partition never analyzed), and the per-partition live/dead tuples, scan counters and…
read-onlyany connectionsweeps instancesweeps replication groupsweeps group
partitionDetails(schema, table, [limit], [order_by])
Return one partitioned table with every partition: its bound expression verbatim, whether it is the DEFAULT, whether it is itself partitioned, estimated rows and size (both null, not 0, for a partition never analyzed), and the per-partition live/dead tuples, scan counters and vacuum and analyze timestamps. Those statistics are the reason this exists: autovacuum runs per PARTITION, so a parent has no vacuum state of its own and ranking parents finds nothing while one child falls behind.
Bounds are returned verbatim rather than parsed -- a bound carries whatever types the key columns have, and a misparsed boundary is worse than an unparsed one; for a RANGE parent, comparing the highest upper bound against now() is how to see that next period's partition was never created. counters_since says when the scan counters were last reset, and counters_since_source which view said so: pg_stat_database, or the earliest of the server-wide views where the database carries no reset time, as after crash recovery on PostgreSQL 15 and later.
Returns a clear error naming the relkind if the table exists but is not partitioned. At most limit partitions are returned, 100 by default, with partition_count and partitions_truncated beside them: on a table partitioned by day each partition costs about 400 bytes, so three years of them is ~430 KB. To find the partition falling behind, rank with order_by=dead_tuples or oldest_vacuum rather than reading them by name.
partition_count and partitions_truncated say how many there are; the DEFAULT partition is always keptdead_tuples, mod_since_analyze, oldest_vacuum (never-vacuumed first), or sizeAlso accepts connection, instance, replication_group, group, role, described once under arguments every tool takes.
One partitioned table and its partitions, at most `limit` of them. An absent extension or a missing grant is reported as {error, hint} instead.
| Field | Type |
|---|---|
| counters_since | string | null |
| counters_since_source | string | null |
| is_partition_of | string | null |
| key | string | null |
| order_by | string | null |
| partition_count | integer | null |
| partitions | array | null |
| partitions_truncated | boolean | null |
| strategy | string | null |
| table | string | null |
The counters here are each server's own, so members of a replication group legitimately disagree and the answer is their sum, not the primary's copy. Dead tuples and the last vacuum and analyze times describe work that only happens on a primary; on a replica they are noise, not a second opinion.
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "partitionDetails",
"arguments": {
"schema": "shop",
"table": "events"
}
}
}
{
"table": "events",
"strategy": "range",
"key": "RANGE (created_at)",
"is_partition_of": null,
"counters_since": "2026-08-01T00:00:00Z",
"counters_since_source": "pg_stat_database",
"partition_count": 2,
"partitions_truncated": false,
"order_by": "name",
"partitions": [
{
"name": "events_2026_08",
"schema": "shop",
"bound": "FOR VALUES FROM ('2026-08-01 00:00:00+00') TO ('2026-09-01 00:00:00+00')",
"is_default": false,
"is_partitioned": false,
"rows": 7340112,
"size_estimate": 1182990336,
"n_dead_tup": 20431,
"last_autovacuum": "2026-09-02T03:11:40Z"
},
{
"name": "events_default",
"schema": "shop",
"bound": "DEFAULT",
"is_default": true,
"is_partitioned": false,
"rows": 412,
"size_estimate": 57344,
"n_dead_tup": 0,
"last_autovacuum": null
}
]
}
Invented values on a fictional shop database, shaped by and checked against this tool's output schema. Real output is returned as structuredContent to clients that negotiate MCP 2025-06-18 or later.
listSchemas, listTables, tableDetails, tableStats, largeObjects, listPartitions, listTableStats, tableSize, listTableSizes, listFunctions, functionDetails, listEnums, enumDetails, listTypes, typeDetails, columnHistogram, listExtendedStatistics, listSequences