pg-logical-mcp
Diagnoses Postgres logical replication: slot WAL retention, walsender lag, stuck subscriptions, with gated remediation.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@pg-logical-mcpcheck replication slots health"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
pg-logical-mcp
Diagnose Postgres logical replication: slot WAL retention, walsender lag, stuck subscriptions, with gated remediation.
An MCP server that lets an AI agent introspect and reason about a PostgreSQL logical replication / CDC setup — replication slots and WAL retention, walsender and decoding pressure, publications, subscriptions, and stuck-apply diagnosis — plus a small set of gated remediation tools.
It deliberately does not compete in the crowded "query optimizer / index advisor" MCP space. It targets the replication/CDC layer, which is largely untooled and where a lot of real production incidents come from.
The design point: deterministic gate + judgment
Two layers, explicitly separated:
Deterministic tools return raw catalog/stats state. They keep the agent grounded in facts and are individually testable. (
list_replication_slots,inspect_walsenders,decoding_stats,list_publications,inspect_subscriptions,subscription_errors,peek_changes.)Judgment tools synthesise that state into "here's what's wrong and what you can do." This is where the reasoning earns its place. (
assess_slot_risk,check_publication_coverage,diagnose_stuck_subscription.)
Dangerous operations sit behind deterministic guardrails: the model can recommend a slot drop or a transaction skip, but is structurally prevented from fat-fingering a data-losing operation. This is the same deterministic-gate-plus-judgment split used in the companion pre-commit-review hook — the two pieces read as one coherent point of view: let the model reason, but put the irreversible levers behind a deterministic lock it cannot pick.
The judgment logic lives in diagnostics.py as pure functions over provider
output, so it is unit-tested with no live database (tests/test_diagnostics.py).
Related MCP server: PostgreSQL-Performance-Tuner-Mcp
Tools
Slot health & WAL retention (run against the publisher)
list_replication_slots(deterministic) —pg_replication_slotsplus WAL pinned per slot,wal_status,safe_wal_size, active state, holding pid.assess_slot_risk(judgment) — samples the WAL generation rate and, againstmax_slot_wal_keep_size, projects which slot is closest to invalidation and a rough time-to-invalidation / time-to-disk-fill. The differentiated diagnostic no incumbent does.
Publisher side
inspect_walsenders(deterministic) —pg_stat_replication: state, write/flush/replay lag (intervals and LSN diffs),sync_state.decoding_stats(deterministic) —pg_stat_replication_slots:spill_txns/spill_bytesand streaming stats. Surfaces large-transaction decode spill, a real, obscure slowness cause.
Publications
list_publications(deterministic) —pg_publication/pg_publication_tableswith row filters, column lists, published operations.check_publication_coverage(judgment) — flags the two silent failures: a table never added to the publication, and a published table whoseREPLICA IDENTITYwon't support UPDATE/DELETE. Both lose data quietly rather than erroring.
Subscriber side (run against the subscriber)
inspect_subscriptions(deterministic) —pg_subscriptionjoined withpg_stat_subscription. The connection string is omitted (it holds a password).subscription_errors(deterministic) —pg_stat_subscription_statsapply/sync error counts.diagnose_stuck_subscription(judgment, marquee) — correlates error state with the LSN apply is wedged at, explains why apply is blocked (typically a unique-constraint conflict on the subscriber), and lays out the two real options: resolve the conflicting row, or skip the offending transaction.
CDC stream inspection
peek_changes(deterministic) — wrapspg_logical_slot_peek_changes(the peek variant, notget), so inspecting the queue does not consume it or advance the slot.
Gated remediation
advance_slot,skip_apply_transaction,drop_slot— each mutates irreversible state. Every one:is read-only unless the server was started with
PG_LOGICAL_MCP_ALLOW_WRITESset and the call passesallow_writes=true(a two-key gate the model can't fully turn on its own);requires the exact slot name / subscription name and the exact LSN — there is no "advance to latest" / "skip to head" convenience that silently discards an unknown amount of data;
returns a dry-run preview before it will execute.
Install & configure
Published to PyPI; run it with uvx or pipx — no clone required:
// MCP client config — one entry per node you want to inspect.
{
"mcpServers": {
"pg-publisher": {
"command": "uvx",
"args": ["pg-logical-mcp"],
"env": { "PG_LOGICAL_MCP_DSN": "host=publisher.internal port=5432 user=replmon dbname=appdb" }
},
"pg-subscriber": {
"command": "uvx",
"args": ["pg-logical-mcp"],
"env": { "PG_LOGICAL_MCP_DSN": "host=subscriber.internal port=5432 user=replmon dbname=appdb" }
}
}
}Each server points at one node. Slots/walsenders/publications live on the
publisher; subscriptions live on the subscriber — so to see both sides, add both
entries. Connection details come from PG_LOGICAL_MCP_DSN (or the standard
PG* libpq env vars). Provide the password via .pgpass or PGPASSWORD rather
than embedding it where it might be logged.
To enable the remediation tools, add "PG_LOGICAL_MCP_ALLOW_WRITES": "1" to that
server's env. Leave it unset and the server is strictly read-only.
Privileges (stated plainly)
Reading pg_subscription and the subscription stats views needs elevated
privileges. The demo containers run as the postgres superuser for simplicity.
Production use should use a deliberately scoped role, not superuser — grant
only what the tools read (pg_monitor covers most stats views; reading
pg_subscription and using the replication functions needs more). Treat the
remediation tools as privileged operations and gate them at the role level too,
not just with PG_LOGICAL_MCP_ALLOW_WRITES.
Hosting: local only, by design
The author hosts nothing. This ships as a local subprocess your MCP client launches over stdio. This tool needs elevated privileges and a path into the replication subsystem — often in production. A hosted model would mean the author holding your credentials and a route into your production database: unacceptable exposure for everyone. Local means the author never touches a credential or a customer database. If your team later wants a shared deployment, MCP's HTTP transport lets you self-host it near your own database — your deployment decision, not a hosted service.
Demo: see it work in ~2 minutes
Local containers, no infrastructure of your own touched:
docker compose -f docker/docker-compose.yml up -d # publisher :5433, subscriber :5434
# Scenario 1 — wedge a subscription on a primary-key conflict
python scenarios/stuck_subscription.py
# then ask the agent: run diagnose_stuck_subscription against the subscriber
# Scenario 2 — pin a growing pile of WAL behind an inactive slot
python scenarios/slot_retention.py
# then ask the agent: run assess_slot_risk against the publisher
python scenarios/slot_retention.py --recover # restart subscriber, drain the slotPoint the MCP client's pg-publisher entry at host=localhost port=5433 and
pg-subscriber at host=localhost port=5434 (user/password postgres, db
appdb) to drive the tools against the demo.
Development
uv venv && uv pip install -e ".[dev]"
pytest # exercises the pure judgment layer, no DB neededSee CLAUDE.md for architecture and conventions.
License
GPL-3.0-or-later. See LICENSE.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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/esauro/pg-logical-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server