.claude/skills/mt-local-cluster/SKILL.md
Manage local multigres cluster components (multipooler, pgctld, multiorch, multigateway) - start/stop services, view logs, connect with psql, test S3 backups locally
npx skillsauth add multigres/multigres Local Cluster ManagerInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Manage local multigres cluster - both cluster-wide operations and individual components.
Invoke this skill when the user asks to:
Parse ./multigres_local/multigres.yaml once when this skill is first invoked and cache the cluster configuration in memory for the duration of the conversation. Use the cached data for all subsequent commands. Only re-parse if the user explicitly asks to "reload config" or if a command fails due to stale config.
Start entire cluster:
./bin/multigres cluster start
Stop entire cluster:
./bin/multigres cluster stop
Stop entire cluster and delete all cluster data:
./bin/multigres cluster stop --clean
Check cluster status:
./bin/multigres cluster status
Initialize new cluster:
./bin/multigres cluster init
Get all multipoolers from topology:
./bin/multigres getpoolers
Returns JSON with all multipoolers, their cells, service IDs, ports, and pooler directories.
Get detailed status for a specific multipooler:
./bin/multigres getpoolerstatus --cell <cell-name> --service-id <service-id>
Returns detailed status including:
pooler_type: 1 = PRIMARY, 2 = REPLICApostgres_role: "primary" or "standby"postgres_running: Whether PostgreSQL is runningwal_position: Current WAL positionconsensus_term: Current consensus termprimary_status: (for PRIMARY) connected followers and sync replication configreplication_status: (for REPLICA) replication lag and primary connection infoExample:
./bin/multigres getpoolerstatus --cell zone1 --service-id thhcdhbp
Check PostgreSQL recovery mode directly:
psql -h <pooler-dir>/pg_sockets -p <pg-port> -U postgres -d postgres -c "SELECT pg_is_in_recovery();"
Returns t (true) if in recovery/standby mode, f (false) if primary.
Test S3 backups using AWS S3. When the user wants to test S3 backups:
Configuration Caching: When S3 configuration values are first provided, cache them in memory for the duration of the conversation. Reuse these cached values for all subsequent S3 operations. Only re-prompt if:
Prompt for S3 configuration using AskUserQuestion (only if not already cached):
./.staging-aws or ~/.aws/credentials)s3://bucket-name/backups/)us-east-1)Check/source credentials:
# Check if AWS credentials are already set
env | grep AWS_
# If not, source the credentials file (path from user)
source <credentials-file-path>
# Verify credentials are now set
env | grep AWS_
IMPORTANT:
./bin/multigres cluster stop --clean
rm -rf multigres_local
./bin/multigres cluster init \
--backup-url=<s3-url-from-user> \
--region=<region-from-user>
Start cluster (use standard cluster start command)
Verify S3 configuration:
grep -r "aws_access_key_id\|aws_secret_access_key\|region\|repo1-s3" ./multigres_local/data/pooler_*/pgbackrest.conf
Should see AWS credentials and S3 configuration in all pgbackrest.conf files.
Create backup:
./bin/multigres cluster backup
List all backups:
./bin/multigres cluster list-backups
Restore from backup:
./bin/multigres cluster restore --backup-label <label>
Missing/expired credentials:
# Re-source credentials file
source <credentials-file-path>
# Verify they're set
env | grep AWS_ | wc -l # Should show 3+ environment variables
# Reinitialize cluster to pick up new credentials
./bin/multigres cluster stop --clean
rm -rf multigres_local
./bin/multigres cluster init --backup-url=<s3-url> --region=<region>
Check pgbackrest logs for errors:
# View recent errors
tail -100 ./multigres_local/data/pooler_*/pg_data/log/pgbackrest-*.log
# Follow logs in real-time
tail -f ./multigres_local/data/pooler_*/pg_data/log/pgbackrest-*.log
Verify S3 bucket access:
# Use AWS CLI to test bucket access (if installed)
aws s3 ls <s3-bucket-path> --region <region>
Start the observability stack (Grafana + Prometheus + Loki + Tempo) for metrics, traces, and logs visualization.
Start cluster with observability:
# 1. Start observability stack (separate terminal, runs in foreground)
demo/local/run-observability.sh
# 2. Start cluster with OTel export (separate terminal)
demo/local/multigres-with-otel.sh cluster start --config-path <config-path>
Generate traffic with pgbench:
Run pgbench init synchronously first, then start the workload in a background Agent so the user sees the output when it completes (do NOT use run_in_background on Bash — that hides output).
# Step 1: Init (synchronous)
PGPASSWORD=postgres pgbench -h localhost -p 15432 -U postgres -i postgres
# Step 2: Workload (run in a background Agent)
PGPASSWORD=postgres pgbench -h localhost -p 15432 -U postgres -c 4 -j 2 -T 300 -P 5 postgres
View telemetry:
Teardown (stop in this order to avoid OTel export errors):
# 1. Stop the cluster first
./bin/multigres cluster stop --config-path <config-path>
# 2. Stop the observability stack
docker rm -f multigres-observability
Full restart:
# Teardown
./bin/multigres cluster stop --config-path <config-path>
docker rm -f multigres-observability
# Start
demo/local/run-observability.sh # terminal 1
demo/local/multigres-with-otel.sh cluster start --config-path <config-path> # terminal 2
Observability ports:
| Service | Port | | ----------- | ---- | | Grafana | 3000 | | OTLP (HTTP) | 4318 | | Prometheus | 9090 | | Loki | 3100 | | Tempo | 3200 |
Parse the config: Read ./multigres_local/multigres.yaml to discover available components and their IDs
Component ID mapping:
.provisioner-config.cells.<zone>.multipooler.service-idIf no ID provided: Use AskUserQuestion to let the user select which instance to operate on
Stop pgctld:
./bin/pgctld stop --pooler-dir <pooler-dir-from-config>
Start pgctld:
./bin/pgctld start --pooler-dir <pooler-dir-from-config>
Restart pgctld (as standby):
./bin/pgctld restart --pooler-dir <pooler-dir-from-config> --as-standby
Check pgctld status:
./bin/pgctld status --pooler-dir <pooler-dir-from-config>
View logs:
./multigres_local/logs/dbs/postgres/multipooler/[id].log./multigres_local/logs/dbs/postgres/pgctld/[id].log./multigres_local/logs/dbs/postgres/multiorch/[id].log./multigres_local/logs/dbs/postgres/multigateway/[id].log./multigres_local/data/pooler_[id]/pg_data/postgresql.logTail logs:
tail -f <log-path>
Connect to multipooler (via Unix socket):
psql -h <pooler-dir>/pg_sockets -p <pg-port> -U postgres -d postgres
Where:
.provisioner-config.cells.<zone>.multipooler.pooler-dir.provisioner-config.cells.<zone>.pgctld.pg-port<pooler-dir>/pg_sockets/.s.PGSQL.<pg-port>Example:
psql -h ./multigres_local/data/pooler_xf42rpl6/pg_sockets -p 25432 -U postgres -d postgres
Connect to multigateway (via TCP):
psql -h localhost -p <pg-port> -U postgres -d postgres
Where:
.provisioner-config.cells.<zone>.multigateway.pg-portExample:
psql -h localhost -p 15432 -U postgres -d postgres
Extract from YAML config at .provisioner-config.cells.<zone>.pgctld.pooler-dir
Cluster-wide:
User: "start the cluster"
./bin/multigres cluster startUser: "stop cluster"
./bin/multigres cluster stopUser: "cluster status"
./bin/multigres cluster statusUser: "show me all multipoolers" or "get poolers"
./bin/multigres getpoolersUser: "check if multipoolers are in recovery" or "check multipooler status"
./bin/multigres getpoolerstatus --cell <zone> --service-id <id> for eachUser: "check zone1 multipooler status"
./bin/multigres getpoolerstatus --cell zone1 --service-id <id>Observability:
User: "start cluster with otel" or "start cluster with observability"
demo/local/run-observability.sh (if not running)demo/local/multigres-with-otel.sh cluster start --config-path <path>User: "teardown everything" or "stop everything"
./bin/multigres cluster stop --config-path <path>docker rm -f multigres-observabilityUser: "restart everything" or "full restart"
User: "push traffic" or "generate load"
-P 5 for progressIndividual components:
User: "stop pgctld"
User: "restart pgctld xf42rpl6 as standby"
./bin/pgctld restart --pooler-dir /path/to/pooler_xf42rpl6 --as-standbyUser: "logs multipooler hm9hmxzm"
./multigres_local/logs/dbs/postgres/multipooler/hm9hmxzm.logUser: "tail pgctld"
User: "connect to multipooler zone1" or "psql multipooler xf42rpl6"
psql -h <pooler-dir>/pg_sockets -p <pg-port> -U postgres -d postgresUser: "connect to multigateway" or "psql multigateway"
psql -h localhost -p <pg-port> -U postgres -d postgrestools
Run unit tests, integration tests, and development tasks for multigres
development
Fix markdown linting and prettier formatting issues in markdown files
data-ai
Generate a PR title and description from the current branch diff against main
testing
Create, edit, improve, or audit AgentSkills. Use when creating a new skill from scratch or when asked to improve, review, audit, tidy up, or clean up an existing skill or SKILL.md file. Also use when editing or restructuring a skill directory (moving files to references/ or scripts/, removing stale content, validating against the AgentSkills spec). Triggers on phrases like "create a skill", "author a skill", "tidy up a skill", "improve this skill", "review the skill", "clean up the skill", "audit the skill".