CLI Reference#

Complete reference for all pgmi commands. Every example is copy-paste ready.

For a guided walkthrough, see Quickstart .


Global Flags#

These flags work with every command:

FlagDescription
-v, --verboseEnable verbose output (also shows PostgreSQL RAISE DEBUG messages)
-h, --helpShow help for any command

pgmi deploy#

Execute a database deployment.

pgmi deploy <project_path> [flags]

pgmi connects to PostgreSQL, loads your project files into session temp tables, then runs deploy.sql which directly executes your files.

Connection Flags#

FlagDefaultDescription
--connection$PGMI_CONNECTION_STRING or $DATABASE_URLFull connection string (PostgreSQL URI or ADO.NET). Mutually exclusive with granular flags.
--host$PGHOST or localhostPostgreSQL server host
-p, --port$PGPORT or 5432PostgreSQL server port
-U, --username$PGUSER or OS userPostgreSQL user
-d, --database$PGDATABASE or from connection stringTarget database name
--sslmode$PGSSLMODE or preferSSL mode: disable, allow, prefer, require, verify-ca, verify-full
--sslcert$PGSSLCERTPath to client SSL certificate file
--sslkey$PGSSLKEYPath to client SSL private key file
--sslrootcert$PGSSLROOTCERTPath to root CA certificate for server verification

Deployment Flags#

FlagDescription
--overwriteDrop and recreate the target database before deploying. Local development only.
--forceReplace interactive confirmation with 5-second countdown. Still shows warning, still cancellable with Ctrl+C.
--timeoutCatastrophic failure protection (default: 3m). Examples: 30s, 5m, 1h30m
--compatAPI compatibility version (default: latest). Pin to a specific version for stable CI/CD pipelines.

Understanding --compat (API Versioning)#

The --compat flag pins your deployment to a specific pgmi session API version. This ensures your deploy.sql continues working even when pgmi upgrades introduce new features or internal changes.

Currently supported versions:

VersionStatusNotes
1Current / LatestInitial stable API

When to use --compat:

# CI/CD pipelines: pin to a specific version for reproducibility
pgmi deploy . -d myapp --compat=1

# Local development: use latest (default, no flag needed)
pgmi deploy . -d myapp

What the API version controls:

  • Session views: pg_temp.pgmi_source_view, pg_temp.pgmi_plan_view, pg_temp.pgmi_parameter_view, etc.
  • Public functions: pg_temp.pgmi_test_plan(), pg_temp.pgmi_test_generate()
  • Column names and types in views

What it does NOT control:

  • CLI flags and behavior (CLI versioning is separate)
  • Internal tables (_pgmi_*) — these are implementation details

Error handling:

# Invalid version returns clear error with supported versions
$ pgmi deploy . --compat=99
Error: unsupported API version "99"; supported: [1]

Best practice: Pin --compat in CI/CD pipelines for stability. When upgrading pgmi, test with the new default version before updating your pinned version.

API Version Changelog#

Version 1 (Current)

  • Initial stable API release
  • Views: pgmi_source_view, pgmi_plan_view, pgmi_parameter_view, pgmi_test_source_view, pgmi_test_directory_view, pgmi_source_metadata_view
  • Functions: pgmi_test_plan(), pgmi_test_generate(), pgmi_is_sql_file(), pgmi_persist_test_plan()
  • Preprocessor macro: CALL pgmi_test()

See Session API for complete API documentation.

Understanding --overwrite Safety#

The --overwrite flag triggers a destructive operation: the target database is dropped and recreated. pgmi provides safety mechanisms to prevent accidents:

Without --force (interactive mode):

⚠️  WARNING: You are about to DROP and RECREATE the database 'myapp'
This will permanently delete all data in this database!

To confirm, type the database name 'myapp' and press Enter: _

You must type the exact database name. Typos cancel the operation.

With --force (countdown mode):

╔═══════════════════════════════════════════════════════════════════════╗
      ______
   .-'      '-.
  /            \           ⚠️  DANGER: DESTRUCTIVE OPERATION ⚠️
 |,  .-.  .-.  ,|       Database 'myapp' will be PERMANENTLY DELETED
 | )(_o/  \o_)( |                ALL DATA WILL BE LOST
  \__|IIIIII|__/
╚═══════════════════════════════════════════════════════════════════════╝

Dropping in: 5 seconds... (Press Ctrl+C to cancel)

A 5-second countdown gives you time to cancel with Ctrl+C.

When to use --overwrite:

  • Local development with disposable databases
  • CI/CD pipelines deploying to ephemeral test databases (not production!)
  • Never on production or staging databases with real data

Parameter Flags#

FlagDescription
--param key=valueSet a parameter (repeatable). Accessible in SQL via current_setting('pgmi.key')
--params-file pathLoad parameters from .env file (repeatable, later files override earlier ones)

Azure Entra ID Flags#

FlagDescription
--azureEnable Azure Entra ID authentication. Uses DefaultAzureCredential chain (Managed Identity, Azure CLI, etc.)
--azure-tenant-idAzure AD tenant/directory ID (overrides $AZURE_TENANT_ID)
--azure-client-idAzure AD application/client ID (overrides $AZURE_CLIENT_ID)

AWS IAM Flags#

FlagDescription
--awsEnable AWS IAM database authentication. Uses default AWS credential chain (env vars, config file, IAM role, etc.)
--aws-regionAWS region for RDS endpoint (overrides $AWS_REGION)

Google Cloud SQL IAM Flags#

FlagDescription
--googleEnable Google Cloud SQL IAM database authentication. Uses Application Default Credentials (gcloud auth, service account, etc.)
--google-instanceCloud SQL instance connection name (format: project:region:instance). Required when --google is specified.

Password#

Passwords are never passed as CLI flags. Use one of:

# Environment variable
export PGPASSWORD="your-password"

# Connection string
pgmi deploy . --connection "postgresql://user:pass@localhost:5432/postgres" -d myapp

# .pgpass file (PostgreSQL standard)
# ~/.pgpass format: hostname:port:database:username:password

Examples#

# Deploy (creates the database if new, deploys incrementally if it exists)
pgmi deploy ./myproject -d myapp

# Recreate database for local development (shows 5-second countdown)
pgmi deploy ./myproject -d myapp_dev --overwrite --force

# Full connection string
pgmi deploy ./myproject --connection "postgresql://postgres:secret@db.example.com:5432/postgres" -d myapp

# Pin to specific API version for CI/CD stability
pgmi deploy ./myproject -d myapp --compat=1

# With parameters
pgmi deploy ./myproject -d myapp --param env=production --param version=2.1.0

# Parameters from file + CLI override
pgmi deploy ./myproject -d myapp \
  --params-file base.env \
  --params-file prod.env \
  --param version=2.1.0

# Longer timeout for large deployments
pgmi deploy ./myproject -d myapp --timeout 30m

# Verbose output (see RAISE DEBUG messages)
pgmi deploy ./myproject -d myapp --verbose

# Azure Entra ID with Managed Identity (no credentials needed)
pgmi deploy ./myproject -d myapp --azure \
  --host myserver.postgres.database.azure.com \
  --sslmode require

# Azure Entra ID with Service Principal
pgmi deploy ./myproject -d myapp \
  --azure-tenant-id "your-tenant-id" \
  --azure-client-id "your-client-id"

# mTLS with client certificate
pgmi deploy ./myproject -d myapp \
  --sslmode verify-full \
  --sslcert /path/to/client.crt \
  --sslkey /path/to/client.key \
  --sslrootcert /path/to/ca.crt

# mTLS combined with connection string
pgmi deploy ./myproject \
  --connection "postgresql://user@host/postgres" -d myapp \
  --sslcert /path/to/client.crt \
  --sslkey /path/to/client.key

The Two-Database Pattern#

The connection string specifies the maintenance database (used to run CREATE DATABASE). The -d flag specifies the target database (the one being created/deployed to):

# Connect to 'postgres' (maintenance), create and deploy to 'myapp' (target)
pgmi deploy . --connection "postgresql://user@host/postgres" -d myapp

pgmi info#

Show a project structure summary without connecting to a database.

pgmi info [path] [flags]

Inspects a pgmi project directory and reports file counts by directory, template type, deploy.sql presence, test coverage, and metadata usage.

FlagDescription
--jsonEmit structured JSON to stdout

Examples#

# Inspect current directory
pgmi info

# Inspect a specific project
pgmi info ./myproject

# JSON output for scripting
pgmi info ./myproject --json

pgmi init#

Scaffold a new pgmi project.

pgmi init <target_path> [flags]

Creates a ready-to-deploy project structure with deploy.sql, directory layout, and README.

FlagDefaultDescription
-t, --templatebasicTemplate to use (basic or advanced)

Use pgmi templates list to see all available templates with descriptions.

Templates#

TemplatePurpose
basicLow-ceremony, production-capable for small systems. Linear migrations/ with deploy.sql. Runs on any provider.
advancedFull reference app. 4-schema architecture, role hierarchy, metadata-driven deployment. PostgreSQL 15+; needs a role with CREATEROLE + CREATE EXTENSION (no superuser). Runs on managed cloud — see the Production Guide .

Examples#

# Create a project in the current directory
pgmi init .

# Create a named project with the basic template
pgmi init myapp

# Production-ready project
pgmi init myapp --template advanced

# See available templates
pgmi templates list

pgmi metadata#

Offline metadata operations (no database connection required).

pgmi metadata scaffold#

Generate <pgmi-meta> blocks for SQL files that lack them.

pgmi metadata scaffold <project_path> [flags]
FlagDefaultDescription
--writeWrite metadata to files (without this flag, preview only)
--idempotenttrueMark generated scripts as idempotent
# Preview what would be generated
pgmi metadata scaffold ./myproject

# Write metadata to files
pgmi metadata scaffold ./myproject --write

pgmi metadata validate#

Check metadata for syntax, schema compliance, and duplicate IDs.

pgmi metadata validate <project_path> [flags]
FlagDescription
--jsonOutput results as JSON
pgmi metadata validate ./myproject
pgmi metadata validate ./myproject --json

pgmi metadata plan#

Show the execution plan derived from metadata sort keys.

pgmi metadata plan <project_path> [flags]
FlagDescription
--jsonOutput plan as JSON
pgmi metadata plan ./myproject
pgmi metadata plan ./myproject --json

pgmi templates#

Browse and inspect available project templates.

pgmi templates list#

pgmi templates list

pgmi templates describe#

pgmi templates describe <template_name>
# See what the advanced template includes
pgmi templates describe advanced

pgmi version#

pgmi version

pgmi serve#

Exposes pgmi’s commands as MCP tools over stdio (JSON-RPC 2.0), so MCP-capable assistants (Claude Code, OpenCode) can drive pgmi natively instead of spawning a subprocess and parsing text.

pgmi serve

The tools map 1:1 to existing CLI commands — serve adds no deployment semantics. Connection and parameters are passed per tool call and never stored in server state. Tools exposed: deploy, init, metadata_plan, metadata_validate, templates_list, ai_overview, ai_skills, ai_skill, ai_contract.

Register it with Claude Code:

claude mcp add pgmi -- pgmi serve

The server reads JSON-RPC from stdin, writes responses to stdout, and sends all diagnostics to stderr. It exits cleanly on EOF or SIGINT.

This is pgmi’s own CLI as MCP tools. It is unrelated to the advanced template’s MCP gateway (which exposes your deployed database to agents — see docs/MCP.md ).


pgmi ai#

AI-digestible documentation for coding assistants. Outputs structured markdown that AI tools can parse and learn from.

pgmi ai (overview)#

pgmi ai

Outputs an overview document similar to llms.txt format, explaining:

  • What pgmi is and its philosophy
  • Core concepts (session tables, deploy.sql pattern)
  • Quick start commands
  • Available skills and when to use them
  • Key SQL conventions

pgmi ai skills#

pgmi ai skills

Lists all embedded skills with descriptions:

# Available pgmi Skills

| Skill | Description |
|-------|-------------|
| `pgmi-sql` | Use when writing SQL/PL/pgSQL or deploy.sql |
| `pgmi-philosophy` | Architectural decisions, execution fabric vs migration framework |
| `pgmi-cli` | Use when adding CLI commands or flags |
...

pgmi ai skill#

pgmi ai skill <name>

Outputs the full content of a specific skill. Use this to load detailed conventions for a particular domain:

# Load SQL conventions
pgmi ai skill pgmi-sql

# Load CLI design patterns
pgmi ai skill pgmi-cli

# Load testing patterns
pgmi ai skill pgmi-testing-review

pgmi ai contract#

pgmi ai contract

Prints the machine-readable session-API contract as JSON. Agents should query this before writing SQL against pgmi views/functions to avoid hallucinating identifiers. Output includes view names and columns, test function signatures, step types, exit codes, and preprocessor macro forms.

pgmi ai client#

pgmi ai client [lang]

Prints guidance for generating a typed API client from a deployment’s live OpenAPI spec (the advanced template serves it at GET /openapi.json). Without a language, prints the language-agnostic doctrine (decision tree, invariants, anti-copy directive). With a language, adds a transport-core skeleton and the recommended generator:

pgmi ai client              # doctrine only
pgmi ai client typescript   # + openapi-typescript
pgmi ai client python       # + openapi-python-client
pgmi ai client go           # + oapi-codegen
pgmi ai client csharp       # + NSwag
pgmi ai client rust         # + openapi-generator

This covers the application API (your deployed handlers). For the session API (the temp views/functions deploy.sql consumes), use pgmi ai contract.

pgmi ai setup#

pgmi ai setup [--assistant <name> | --all] [--global] [--dry-run] [--force]
              [--claude-md | --no-claude-md]

Materializes pgmi guidance into a coding assistant’s skill directory so the assistant learns the execution model before it edits the project. Defaults to the Claude skill under .claude/skills/pgmi/ (project-local, safe to commit).

AssistantLocal target
claude (default).claude/skills/pgmi/
agents (aliases: codex, opencode)AGENTS.md
codex-skills.codex/skills/pgmi/
antigravity.agents/skills/pgmi/
cursor.cursor/rules/pgmi.mdc
copilot.github/copilot-instructions.md
windsurf.windsurf/rules/pgmi.md
cline.clinerules/pgmi.md
geminiGEMINI.md

--global writes under your home directory instead of the project (e.g. ~/.claude/skills/pgmi/, ~/.codex/skills/pgmi/, ~/.gemini/GEMINI.md).

pgmi ai setup                        # detect .claude/, write the Claude skill
pgmi ai setup --assistant agents     # write AGENTS.md (Codex, opencode, etc.)
pgmi ai setup --assistant cursor     # write .cursor/rules/pgmi.mdc
pgmi ai setup --all                  # write one file per distinct target
pgmi ai setup --global               # write to ~/.claude/skills/pgmi/ instead
pgmi ai setup --dry-run              # print planned changes, write nothing

The generated skill is self-contained — it teaches the core model even with no pgmi binary installed — and points to pgmi ai skill <name> for depth. Files are stamped; re-running is idempotent and a hand-edited file is not overwritten without --force. setup also offers a one-line managed pointer in the project CLAUDE.md (--claude-md / --no-claude-md to decide non-interactively).

In non-interactive contexts (CI), pass --assistant explicitly.

pgmi ai check#

pgmi ai check [--assistant claude] [--global]

Reports whether the guidance exists and whether it matches this binary’s version. Exits non-zero when guidance is missing, stale, or hand-edited, so it can gate CI:

pgmi ai check || pgmi ai setup --assistant claude

AI Workflow Example#

When an AI assistant encounters “use pgmi for my project”:

# Step 1: Discover AI documentation exists
pgmi --help | grep ai

# Step 2: Get overview
pgmi ai

# Step 3: List available skills
pgmi ai skills

# Step 4: Load relevant skill
pgmi ai skill pgmi-sql

# Step 5: AI now understands pgmi conventions

Environment Variables#

pgmi respects standard PostgreSQL environment variables and its own:

VariableUsed byDescription
PGMI_CONNECTION_STRINGdeployFull connection string (highest priority)
DATABASE_URLdeployFull connection string (fallback)
PGHOSTdeployServer host
PGPORTdeployServer port
PGUSERdeployUsername
PGPASSWORDdeployPassword
PGDATABASEdeployDatabase name
PGSSLMODEdeploySSL mode
PGSSLCERTdeployClient SSL certificate path
PGSSLKEYdeployClient SSL private key path
PGSSLROOTCERTdeployRoot CA certificate path
PGSSLPASSWORDdeployPassword for encrypted client key
PGAPPNAMEdeployapplication_name reported in pg_stat_activity (default: pgmi)
PGCONNECT_TIMEOUTdeployConnection timeout in seconds (libpq convention)
PGPASSFILEdeployPath to .pgpass (default: ~/.pgpass or %APPDATA%\postgresql\pgpass.conf)
PGMI_NON_INTERACTIVEanySet to 1 to disable TUI wizards
CIanyAny non-empty value disables TUI wizards
NO_COLORanyDisables ANSI colors (wizards still run; accessibility signal per https://no-color.org )
AZURE_TENANT_IDdeployAzure AD tenant ID
AZURE_CLIENT_IDdeployAzure AD client ID
AZURE_CLIENT_SECRETdeployAzure AD client secret
AWS_REGIONdeployAWS region for RDS IAM auth
AWS_DEFAULT_REGIONdeployFallback AWS region

pgmi uses the jackc/pgx driver (Go-native, no libpq dependency). All standard PG* environment variables are supported.

Precedence#

CLI flags  >  environment variables  >  pgmi.yaml  >  built-in defaults

Exit Codes#

CodeMeaning
0Success
1General error
2CLI usage error (invalid arguments or flags)
3Panic or unexpected system error
10Invalid configuration or parameters
11Database connection failed
12User denied overwrite approval
13SQL execution failed
14deploy.sql not found
15Concurrent deploy detected
16Operation exceeded --timeout (context deadline exceeded)
130Interrupted by SIGINT (Ctrl-C) — Unix convention 128+SIGINT

Shell Completion#

Generate a completion script for your shell:

# bash
pgmi completion bash > /etc/bash_completion.d/pgmi

# zsh
pgmi completion zsh > "${fpath[1]}/_pgmi"

# fish
pgmi completion fish > ~/.config/fish/completions/pgmi.fish

# PowerShell
pgmi completion powershell | Out-String | Invoke-Expression

Completion covers commands, flags, template names (for init --template), SSL mode values, AI skill names (for ai skill), and assistant names (for ai setup / ai check).


Common Error Messages#

Connection Errors (Exit Code 11)#

ErrorCauseSolution
connection refusedPostgreSQL not running or wrong portCheck pg_isready -h <host> -p <port>
password authentication failedWrong credentialsVerify username/password, check pg_hba.conf
database "X" does not existDatabase not createdCreate with createdb X or use --overwrite for fresh setup
SSL connection requiredServer requires SSLAdd ?sslmode=require to connection string
no pg_hba.conf entryClient IP not allowedAdd entry to pg_hba.conf or use SSH tunnel

SQL Execution Errors (Exit Code 13)#

ErrorCauseSolution
relation "X" does not existTable/view not foundCheck execution order, ensure dependencies run first
function "X" does not existMissing functionRun schema files before files that call functions
permission denied for schemaRole lacks privilegesGrant the deploy role CREATE/USAGE on the schema (or CREATEROLE/CREATE EXTENSION for advanced-template setup)
current transaction is abortedEarlier error in transactionFix the root cause; check RAISE EXCEPTION in your SQL
syntax error at or nearInvalid SQLCheck the file path in error message, fix syntax

Configuration Errors (Exit Code 10)#

ErrorCauseSolution
missing required parameterCLI param not providedAdd --param key=value
unknown parameterParam not declared in session.xmlDeclare in session.xml or remove from CLI
invalid regex patternBad pattern in pgmi_test()Fix POSIX regex syntax
unsupported API versionInvalid --compat valueUse --compat=1 (currently only v1 supported)

File Errors (Exit Code 14)#

ErrorCauseSolution
deploy.sql not foundMissing orchestratorRun pgmi init or create deploy.sql manually
no SQL files foundEmpty projectAdd .sql files to your project directory

Debugging Tips#

  1. Add --verbose to see DEBUG-level PostgreSQL notices
  2. Check the file path in error messages — it tells you which file failed
  3. Run deploy.sql manually with psql -f deploy.sql to isolate issues
  4. Use RAISE NOTICE in your SQL to trace execution flow

Quick Recipes#

CI/CD Pipeline (Production)#

Never use --overwrite in production. Deploy incrementally to existing databases:

# Production deployment - incremental, no database recreation
pgmi deploy ./myproject \
  --host db.example.com \
  --username deployer \
  -d myapp_prod \
  --param env=production \
  --timeout 15m

CI/CD Pipeline (Ephemeral Test Database)#

For CI pipelines that create fresh test databases per run:

# Create ephemeral test database, run tests, then tear down
pgmi deploy ./myproject \
  --host db.example.com \
  --username deployer \
  -d "myapp_ci_${CI_JOB_ID}" \
  --overwrite --force \
  --param env=ci \
  --timeout 10m

# Tests run via CALL pgmi_test() in deploy.sql
# If all tests pass, deployment commits
# If any test fails, deployment rolls back

# Clean up: drop the ephemeral database after tests
# (Use your CI platform's cleanup mechanism)

Local Development#

export PGPASSWORD="postgres"
# Deploy with tests (pgmi_test() in deploy.sql gates the commit)
pgmi deploy . -d myapp_dev --overwrite --force

mTLS Client Certificate#

# CLI flags (additive — works with connection string or granular flags)
pgmi deploy ./myproject -d myapp \
  --sslmode verify-full \
  --sslcert /path/to/client.crt \
  --sslkey /path/to/client.key \
  --sslrootcert /path/to/ca.crt

# Combined with connection string
pgmi deploy ./myproject \
  --connection "postgresql://user@host/postgres" -d myapp \
  --sslcert /path/to/client.crt \
  --sslkey /path/to/client.key \
  --sslrootcert /path/to/ca.crt

# Via environment variables
export PGSSLCERT=/path/to/client.crt
export PGSSLKEY=/path/to/client.key
export PGSSLROOTCERT=/path/to/ca.crt
export PGSSLPASSWORD=keypass  # if key is encrypted
pgmi deploy ./myproject -d myapp --sslmode verify-full

# Via pgmi.yaml (committed, paths are not secrets)
# connection:
#   sslcert: /path/to/client.crt
#   sslkey: /path/to/client.key
#   sslrootcert: /path/to/ca.crt

Azure Entra ID (Passwordless)#

# System-assigned Managed Identity (no credentials needed)
pgmi deploy ./myproject \
  --host myserver.postgres.database.azure.com \
  -d myapp --azure \
  --sslmode require

# User-assigned Managed Identity (specify client ID)
pgmi deploy ./myproject \
  --host myserver.postgres.database.azure.com \
  -d myapp --azure \
  --azure-client-id "your-managed-identity-client-id" \
  --sslmode require

# Service Principal (credentials via env vars)
export AZURE_TENANT_ID="your-tenant-id"
export AZURE_CLIENT_ID="your-client-id"
export AZURE_CLIENT_SECRET="your-client-secret"
pgmi deploy ./myproject \
  --host myserver.postgres.database.azure.com \
  -d myapp --azure \
  --sslmode require

AWS IAM (RDS)#

# IAM role (EC2, ECS, Lambda — no credentials needed)
pgmi deploy ./myproject \
  --host mydb.abc123.us-west-2.rds.amazonaws.com \
  -d myapp -U myuser \
  --aws --aws-region us-west-2 \
  --sslmode require

# IAM user (credentials via env vars or ~/.aws/credentials)
export AWS_ACCESS_KEY_ID="your-access-key"
export AWS_SECRET_ACCESS_KEY="your-secret-key"
pgmi deploy ./myproject \
  --host mydb.abc123.us-west-2.rds.amazonaws.com \
  -d myapp -U myuser \
  --aws --aws-region us-west-2 \
  --sslmode require

# Region from environment
export AWS_REGION="us-west-2"
pgmi deploy ./myproject \
  --host mydb.abc123.us-west-2.rds.amazonaws.com \
  -d myapp -U myuser \
  --aws \
  --sslmode require

Google Cloud SQL IAM#

# Service account (GCE, GKE, Cloud Run — no credentials needed)
pgmi deploy ./myproject \
  -d myapp -U myuser@myproject.iam \
  --google --google-instance myproject:us-central1:myinstance

# Local development with gcloud auth
gcloud auth application-default login
pgmi deploy ./myproject \
  -d myapp -U myuser@myproject.iam \
  --google --google-instance myproject:us-central1:myinstance

# With service account key file
export GOOGLE_APPLICATION_CREDENTIALS="/path/to/key.json"
pgmi deploy ./myproject \
  -d myapp -U myuser@myproject.iam \
  --google --google-instance myproject:us-central1:myinstance