Model Context Protocol server for the Percona Operator for PostgreSQL — manage PostgreSQL + PgBouncer clusters, pooling, backups/PITR, and DR with security modes and access-control flags.
Strong schema definitions and clear descriptions across all 20 tools. All tools have input schemas with proper types and descriptions. Tool names follow verb_noun conventions well (list_, get_, create_, delete_, set_, toggle_, scale_, pause_, promote_, upgrade_, restore_). Descriptions are detailed and action-oriented, typically 100-300 chars, explaining what each tool does and its risk level. However, output schemas are not explicitly documented in the source code, they are inferred from implementation. Tool descriptions are well-written but some parameter descriptions could be more prescriptive about constraints. Error handling is present but generic. Security model (permission gates, audit flags, confirmation patterns) is sophisticated but adds complexity. Overall follows patterns well but has documentation gaps that prevent a higher score.
Create a PerconaPGBackup for a cluster (pgBackRest). repoName selects the configured repo (e.g. repo1 = PVC, repo2 = S3). type maps to a pgBackRest --type option.
Delete a PerconaPGBackup resource. Requires admin mode AND PERCONA_ALLOW_DELETE=true. Irreversible.
Delete a PerconaPGCluster. Requires admin mode AND PERCONA_ALLOW_DELETE=true, and confirmation. Protected clusters are refused. Irreversible — deletes PostgreSQL, PgBouncer, and (per finalizers) data.
Summary of a PerconaPGCluster: state, PostgreSQL size, PgBouncer, version, standby, host.
The full `.status` of a PerconaPGCluster — Patroni members, PostgreSQL/PgBouncer readiness, host, and conditions.
Connection endpoints for a cluster: the primary/replica Service hosts, port, and the declared users (names only — passwords live in Secrets and are never returned).
Output schemas not explicitly documented in source code. Tool descriptions mention what is returned (e.g., 'The full `.status` of a PerconaPGCluster') but formal return type schemas are not visible in the provided code. This forces LLMs to infer output structure from descriptions rather than consulting schema.
Confirmation pattern implemented via elicitation (custom makeConfirmer) rather than MCP's Multi Round-Trip Requests (MRTR). While this works, it does not follow the current spec's structured input_required mechanism. The confirm parameter is human-readable (requires exact cluster name string) which is good UX but shifts burden to the client to collect confirmation.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 65 | 2026-07-28+ | v2 |
The tuned PostgreSQL parameters from `spec.patroni.dynamicConfiguration.postgresql.parameters` (the only correct place to set them — direct postgresql.conf edits are reverted by Patroni).
The PgBouncer settings for a cluster: replicas, pool_mode, and the global pool tunables.
List PerconaPGBackup resources in a namespace, with their state, repo, and completion time.
List PerconaPGCluster resources (PostgreSQL + PgBouncer). Omit `namespace` to list across all namespaces. Results are filtered by the namespace/cluster allowlists; protected clusters are flagged.
List the contexts (clusters) available in the loaded kube-config.
List PerconaPGRestore resources in a namespace, with their target cluster and state.
Set spec.pause. Pausing stops the PostgreSQL and PgBouncer pods (spec is retained) to free resources; resuming brings them back. Useful for parking a dev cluster.
Promote a DR standby cluster to primary by setting spec.standby.enabled=false. The cluster stops replaying from the source repo and begins accepting writes. High-impact — requires admin mode and confirmation.
Create a PerconaPGRestore to restore a cluster from a pgBackRest repo — optionally point-in-time. OVERWRITES the cluster's data. Requires admin mode AND PERCONA_ALLOW_RESTORE=true, and (by default) confirmation. For PITR pass type='time' and a target timestamp.
Set the PostgreSQL instance replica count and/or the PgBouncer replica count for a cluster. PostgreSQL scaling is read-modify-write so other instance settings (resources, volumes) are preserved.
Merge PostgreSQL parameters into spec.patroni.dynamicConfiguration.postgresql.parameters (the correct, Patroni-managed path). Keys are added/overridden; set a value to null to remove it. Some parameters need a rolling restart (the operator sequences replicas before the primary).
Update PgBouncer global pool settings (merged into spec.proxy.pgBouncer.config.global). Common keys: pool_mode (session|transaction|statement), default_pool_size, max_client_conn, min_pool_size, reserve_pool_size, server_idle_timeout, query_wait_timeout, max_db_connections.
Enable or disable a built-in extension via spec.extensions.builtin (pg_stat_monitor, pg_stat_statements, pg_audit, pgvector, pg_repack). Note: preload-requiring extensions also need shared_preload_libraries set (via set_pg_parameters) and a restart before CREATE EXTENSION succeeds.
Create a PerconaPGUpgrade to perform a major PostgreSQL version upgrade (e.g. 17 → 18). Requires admin mode AND PERCONA_ALLOW_UPGRADE=true, and confirmation. You must supply the target images for the operator to use.
Parameter descriptions for numeric ranges (e.g., pgReplicas min=1 max=9, pgbouncerReplicas min=0 max=9) are specified in schema but not reinforced in description text.
Error handling in toErrorResult() (src/server.ts) truncates Kubernetes API errors to 800 chars and provides generic categories (PolicyError, ApiException, generic Error) but does not offer recovery guidance. Per pattern:recovery-guide, errors should suggest next steps (e.g., 'Cluster not found. Use list_clusters() to see available clusters.').
Pagination not implemented for list_* tools (list_clusters, list_backups, list_restores). These tools list resources but do not accept limit/offset parameters or return a total count. Per pattern:paginated-result, large Kubernetes namespaces could return hundreds of resources, exhausting context window.
Resource name parameters accept only cluster/backup/restore names, not IDs or alternative identifiers. While simpler, this requires users to know exact resource names. Per pattern:natural-identifiers, tools should accept partial names or support search/list discovery patterns.