|
| 1 | +# PlanetScale CLI — agent guide |
| 2 | + |
| 3 | +For **any** automated agent or script using `pscale`. Always pass **`--format json`**. Substitute placeholders from the user's request or from prior command output (`org list`, `database list`, `branch list`). |
| 4 | + |
| 5 | +If you only have the installed `pscale` binary, start here: |
| 6 | + |
| 7 | +```bash |
| 8 | +pscale agent-guide --format json |
| 9 | +pscale auth check --format json |
| 10 | +``` |
| 11 | + |
| 12 | +Use direct CLI automation for shell commands and scripts. Use the hosted PlanetScale MCP server for MCP clients. |
| 13 | + |
| 14 | +This file documents **how to invoke `pscale`**. For database assessment, safety review, and operational workflows, install the [PlanetScale skills pack](https://github.com/planetscale/skills) (`14-pscale-cli-automation` covers CLI automation; `00-safe-orchestrator` runs the full review). In application repositories, add a separate **project** `AGENTS.md` with org, database, branch, and approval rules (see skill `09-mcp-agent-operating-model` in that repo). |
| 15 | + |
| 16 | +| Placeholder | Meaning | |
| 17 | +|-------------|---------| |
| 18 | +| `<org>` | Organization name | |
| 19 | +| `<database>` | Database name | |
| 20 | +| `<branch>` | Branch name (pick one with `"ready": true` from `branch list`) | |
| 21 | + |
| 22 | +## Flag placement |
| 23 | + |
| 24 | +- **`--org`** is a flag on resource subcommands (`database`, `branch`, `sql`, `api`, …). It is **not** on root `pscale` — `pscale --org …` fails. |
| 25 | +- **`--format json`** is a global flag. It can go on `pscale` or on the subcommand. |
| 26 | +- Commands with positional args (`sql`, `branch list`, …): put **positionals first**, then flags. |
| 27 | + |
| 28 | +```bash |
| 29 | +# Correct |
| 30 | +pscale auth check --format json |
| 31 | +pscale org list --format json |
| 32 | +pscale database list --org <org> --format json |
| 33 | +pscale branch list <database> --org <org> --format json |
| 34 | +pscale sql <database> <branch> --org <org> --format json --query "SELECT 1" |
| 35 | + |
| 36 | +# Also valid — global --format |
| 37 | +pscale --format json database list --org <org> |
| 38 | + |
| 39 | +# Wrong — unknown flag: --org |
| 40 | +pscale --org <org> database list --format json |
| 41 | +``` |
| 42 | + |
| 43 | +## Workflow |
| 44 | + |
| 45 | +1. **Guide** — discover machine-readable conventions when you do not have this file: |
| 46 | + |
| 47 | + ```bash |
| 48 | + pscale agent-guide --format json |
| 49 | + ``` |
| 50 | + |
| 51 | +2. **Auth** — check before anything else: |
| 52 | + |
| 53 | + ```bash |
| 54 | + pscale auth check --format json |
| 55 | + ``` |
| 56 | + |
| 57 | + `"status": "ok"` and `"authenticated": true` with no blocking `issues` means proceed. `"status": "action_required"` exits non-zero — log in, pick an org, or fix credentials (see `issues` and `next_steps`). |
| 58 | + |
| 59 | +3. **Login** (when not authenticated): |
| 60 | + |
| 61 | + ```bash |
| 62 | + pscale auth login --format json |
| 63 | + ``` |
| 64 | + |
| 65 | + Pending JSON is written to **stderr** while waiting; **stdout** has a single final JSON object when login completes (`status: ok` or `action_required` if org setup fails after credentials are saved). Fields include `verification_url`, `user_code`, and `browser_opened`. Open `verification_url` manually if the browser does not open. Do not retry login in a loop without browser access. |
| 66 | + |
| 67 | +4. **Organization** — use `"organization"` from `auth check`, ask the user, or list orgs: |
| 68 | + |
| 69 | + ```bash |
| 70 | + pscale org list --format json |
| 71 | + ``` |
| 72 | + |
| 73 | + Pass `--org <org>` on resource commands (`database`, `branch`, `sql`, `api`, …). Not on `org list`. |
| 74 | + |
| 75 | +5. **Discover resources** before SQL: |
| 76 | + |
| 77 | + ```bash |
| 78 | + pscale database list --org <org> --format json |
| 79 | + pscale branch list <database> --org <org> --format json |
| 80 | + ``` |
| 81 | + |
| 82 | +6. **Query** (read-only default): |
| 83 | + |
| 84 | + ```bash |
| 85 | + pscale sql <database> <branch> --org <org> --format json --query "SELECT 1" |
| 86 | + ``` |
| 87 | + |
| 88 | +## Flags |
| 89 | + |
| 90 | +| Flag | Purpose | |
| 91 | +|------|---------| |
| 92 | +| `--format json` | JSON on stdout | |
| 93 | +| `--org <org>` | Organization (on resource subcommands only) | |
| 94 | +| `--api-url` | Non-production API base URL — pass on every command when not using production | |
| 95 | + |
| 96 | +## Authentication |
| 97 | + |
| 98 | +`pscale auth login` stores credentials in the OS keychain; agents on the same machine reuse them. |
| 99 | + |
| 100 | +Headless / CI: pass `--service-token-id` and `--service-token` on the subcommand that needs auth. |
| 101 | + |
| 102 | +## SQL |
| 103 | + |
| 104 | +Non-interactive queries. Default **`--role` is `reader`** (unlike `pscale shell`, which defaults to admin). Use `pscale shell` for interactive sessions. |
| 105 | + |
| 106 | +```bash |
| 107 | +# Read (default) |
| 108 | +pscale sql <database> <branch> --org <org> --format json --query "SELECT 1" |
| 109 | + |
| 110 | +# Read from replica |
| 111 | +pscale sql <database> <branch> --org <org> --format json --replica --query "SELECT 1" |
| 112 | + |
| 113 | +# PostgreSQL — optional --dbname (default postgres) |
| 114 | +pscale sql <database> <branch> --org <org> --format json --query "SELECT 1" |
| 115 | + |
| 116 | +# MySQL multi-keyspace — optional --keyspace (default @primary) |
| 117 | +pscale sql <database> <branch> --org <org> --format json --keyspace <keyspace> --query "SELECT 1" |
| 118 | +``` |
| 119 | + |
| 120 | +| Flag | Purpose | |
| 121 | +|------|---------| |
| 122 | +| `--role` | `reader` (default), `writer`, `readwriter`, `admin` — same names as `pscale shell` | |
| 123 | +| `--replica` | Route reads to replicas | |
| 124 | +| `--dbname` | PostgreSQL database name (default `postgres`) | |
| 125 | +| `--keyspace` | MySQL keyspace (default `@primary`) | |
| 126 | +| `--force` | Allow destructive SQL after explicit user approval | |
| 127 | + |
| 128 | +**`--role` by engine** (same as `pscale shell`): |
| 129 | + |
| 130 | +| `--role` | MySQL (Vitess) | PostgreSQL | |
| 131 | +|----------|----------------|------------| |
| 132 | +| `reader` | Branch password, reader role | Ephemeral role inheriting `pg_read_all_data` | |
| 133 | +| `writer` | Branch password, writer role | Role inheriting `pg_write_all_data` | |
| 134 | +| `readwriter` | Branch password, readwriter role | Role inheriting read + write | |
| 135 | +| `admin` | Branch password, admin role | Role inheriting `postgres` | |
| 136 | + |
| 137 | +### Destructive SQL |
| 138 | + |
| 139 | +`DELETE`, `DROP`, and `TRUNCATE` anywhere in a query are blocked by default (word match, not substring — `deleted_at` is fine). Returns `"status": "action_required"` with `"query_kind": "destructive"`. |
| 140 | + |
| 141 | +1. Ask the user to approve the query. |
| 142 | +2. Re-run with `--force` only after they approve: |
| 143 | + |
| 144 | +```bash |
| 145 | +pscale sql <database> <branch> --org <org> --format json --force --query "DELETE FROM ..." |
| 146 | +``` |
| 147 | + |
| 148 | +Never use `--force` without explicit user approval. |
| 149 | + |
| 150 | +### SQL JSON |
| 151 | + |
| 152 | +Success: `status`, `database`, `branch`, `kind` (`mysql` or `postgresql`), `role`, `row_count`, `columns`, `rows`; `replica` when `--replica` was used. |
| 153 | + |
| 154 | +MySQL may return synthetic column names (e.g. `:vtg1 /* INT64 */`). PostgreSQL may use names like `?column?`. |
| 155 | + |
| 156 | +Error: one JSON object on stdout with `status: "error"`, `error`, and `next_steps`. |
| 157 | + |
| 158 | +Destructive SQL without `--force`: `status: "action_required"`, `query_kind: "destructive"`, `issues`, and `next_steps` (includes `--force` retry command). |
| 159 | + |
| 160 | +## API passthrough |
| 161 | + |
| 162 | +```bash |
| 163 | +pscale api --org <org> organizations/<org>/databases |
| 164 | +``` |
| 165 | + |
| 166 | +## MCP |
| 167 | + |
| 168 | +For MCP clients, use the hosted PlanetScale MCP server: |
| 169 | + |
| 170 | +```text |
| 171 | +https://mcp.pscale.dev/mcp/planetscale |
| 172 | +``` |
| 173 | + |
| 174 | +See the current MCP docs: https://planetscale.com/docs/connect/mcp |
| 175 | + |
| 176 | +Do not use the deprecated local `pscale mcp server` path unless you explicitly need backward compatibility with an old setup. |
| 177 | + |
| 178 | +## PlanetScale agent skills |
| 179 | + |
| 180 | +Operational workflows (inventory, safety review, Insights, schema recommendations, Traffic Control) live in the public skills repo — not in this file. |
| 181 | + |
| 182 | +```bash |
| 183 | +git clone https://github.com/planetscale/skills.git && cd skills && script/setup |
| 184 | +# or: npx skills add planetscale/skills -g -y |
| 185 | +``` |
| 186 | + |
| 187 | +After installing skills, load `14-pscale-cli-automation` for CLI conventions (or re-run `pscale agent-guide --format json` from any `pscale` binary that includes agent onboarding). Use `00-safe-orchestrator` when the user asks for a full PlanetScale assessment. |
0 commit comments