Connect to every configured connection and report what each server actually is: its role (primary or replica, from pg_is_in_recovery(), observed now rather than configured), its system identifier, postmaster start time, database, address, port and version -- then check the…
read-only
verifyTopology()
Connect to every configured connection and report what each server actually is: its role (primary or replica, from pg_is_in_recovery(), observed now rather than configured), its system identifier, postmaster start time, database, address, port and version -- then check the declared topology against them. A physical replica carries the same system identifier as its primary forever, so the identifier alone cannot separate the two axes: the same identifier and the same postmaster start time is one instance however it was reached -- directly or through a pooler, whose reported address is its own hop to the server -- and the same identifier with a different start time is another server of the lineage, a replication group.
Reports declarations the servers contradict, connections that share an identifier but are not declared together (an undeclared replica is where 'is this index used?' quietly gets the wrong answer), a replication group with no primary, and split brain. Logical replication cannot be verified this way and is reported as such rather than as a mismatch. A connection declaring pooler = <console> is checked against that console's own routing (SHOW DATABASES): the route is reported beside it, a name it routes to another database or port is an error, a name it does not list is information when the connection works and a warning when it does not (SHOW DATABASES never shows a '*' fallback, so not listed is not unroutable), an alias is noted, and the direct connection that is the same database -- one postmaster, one database, one user -- is named.
Connects once per configured connection, several at a time, with a short connect timeout; a connection that fails is reported and does not abort the rest
None of its own.
Declared topology checked against each server. An absent extension or a missing grant is reported as {error, hint} instead.
| Field | Type |
|---|---|
| connections | array | null |
| findings | array | null |
| invalid | array | null |
| poolers | array | null |
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "verifyTopology",
"arguments": {}
}
}
{
"connections": [
{
"connection": "shop_prod",
"role": "primary",
"system_identifier": "7412203311020332211",
"postmaster_start_time": "2026-09-14 03:12:40.118204+00",
"database": "shop",
"server_addr": "10.0.2.10",
"server_port": 5432,
"server_version": "18.6"
},
{
"connection": "shop_replica_1",
"role": "replica",
"system_identifier": "7412203311020332211",
"postmaster_start_time": "2026-09-14 03:15:02.540911+00",
"database": "shop",
"server_addr": "10.0.2.21",
"server_port": 5432,
"server_version": "18.6"
}
],
"findings": []
}
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.