Royal MCP WP-CLI Commands — Health, Clients, Key Rotation
Royal MCP ships three WP-CLI commands under wp royal-mcp: check what AI clients need from a site, list who is connected through OAuth, and rotate the API key. Each one prints a table by default and switches to JSON, CSV or YAML with a flag, so the same command works in a terminal, a deployment step, or a loop over every site your agency manages.
Before you start
- Requires Royal MCP 1.5.7 or newer. Older versions do not register the
royal-mcpcommand. Confirm withwp plugin get royal-mcp --field=version. - WP-CLI runs as the site, not as a logged-in user. Run the commands from the WordPress root, or pass
--path=/path/to/wordpressfrom anywhere. - Multisite: add
--url=with the sub-site address so the checks and the client list belong to the right site. - Standard WP-CLI flags apply.
--format,--fields,--field,--user,--yesand--quietbehave exactly as they do on core commands.
| Command | What it does | Changes the site? |
|---|---|---|
wp royal-mcp connection-health | Runs the Site Health checks plus the plugin's own state. Exits 1 on a critical finding. | No |
wp royal-mcp list-clients | Lists every AI client and WordPress user signed in through OAuth. | No |
wp royal-mcp rotate-api-key | Replaces the API key and prints the new one once. | Yes |
wp royal-mcp connection-health
Runs the same four checks as Tools › Site Health (permalinks, discovery document, Authorization header reaching WordPress, sign-in addresses reachable) and adds the plugin's own state: version, endpoint, whether the plugin is switched on, read-only mode, which user the API key acts as, how many OAuth connections are live, and which page builders are detected.
Every row carries a status. good and info need nothing from you. recommended is worth a look. critical means no AI client can use the site until it is fixed, and the command exits with status 1 so a script can stop there.
Options
| Flag | Values | Notes |
|---|---|---|
--format=<format> | table (default), json, csv, yaml | Columns are check, status, detail in every format. |
Checks reported
| Check | Possible status | Meaning |
|---|---|---|
plugin_version | info | Installed Royal MCP version. |
endpoint | info | The MCP endpoint URL clients connect to. |
plugin_enabled | good / critical | Critical when Royal MCP is switched off in its settings. |
read_only_mode | info | on means tools that change the site are refused; reads still work. |
api_key_bound_to | info / recommended | The WordPress user the API key acts as. Recommended when no user is bound yet. |
oauth_connections | info | Number of live OAuth connections (the rows list-clients prints). |
permalinks | good / critical | Plain permalinks block the discovery and sign-in routes. |
discovery_document | good / recommended / critical | Whether the OAuth discovery document is served from the site root. |
authorization_header | good / critical | Whether an Authorization header reaches WordPress (some hosts strip it). |
sign_in_addresses | good / critical | Whether the OAuth sign-in routes answer. |
builders | info | Detected page builders: divi, elementor, gutenberg, or none. |
Example: gate a deployment
Run the check as the last step of a deploy. A critical finding fails the step, so a site never goes live with AI clients locked out.
wp royal-mcp connection-health --format=json --path=/var/www/client-site || exit 1
The same four checks appear under Tools › Site Health › Status inside wp-admin, with the fix for each one. The CLI version is for the sites you do not log in to every day.
wp royal-mcp list-clients
Prints one row per AI client and WordPress user that currently holds a live OAuth token: the same rows as Royal MCP › Connected Clients in wp-admin. Use it to answer "who can reach this site through an AI client right now?" without opening the dashboard.
Clients that authenticate with the API key do not sign in, so they never appear here. The API key is a single credential; see api_key_bound_to in connection-health for the user it acts as.
Options
| Flag | Values | Notes |
|---|---|---|
--format=<format> | table (default), json, csv, yaml, ids, count | ids prints client IDs only; count prints the number of connections. |
--fields=<fields> | Comma-separated field names | Limits the columns. Order is kept. |
--field=<field> | One field name | Prints that single value per connection, one per line. |
Available fields
| Field | Meaning |
|---|---|
client_id | The OAuth client identifier the AI client registered with. |
client_name | The name the client announced at registration (Claude, ChatGPT, Cursor, and so on). |
user_login | The WordPress user who signed in to that client. |
user_id | That user's ID. |
live_tokens | How many unexpired tokens the pair holds. |
last_issued | When the most recent token was issued. |
registered | When the client first registered with the site. |
Example: export who is connected, across every site
Collect one CSV per site, then open them side by side or feed them to your reporting. The header row is included once per file.
for site in /var/www/*/; do
wp royal-mcp list-clients --format=csv --fields=client_name,user_login,last_issued --path="$site" \
> "clients-$(basename "$site").csv"
done
Revoking is still done from the dashboard: Royal MCP › Connected Clients has a Revoke access button on every row and a Revoke all button at the top.
wp royal-mcp rotate-api-key
Replaces the site's API key. The old key stops working immediately, the new key is printed once, and nothing readable is stored afterwards. Rotate on a schedule, after staff changes, or the moment you suspect a key has leaked.
The API key acts as a WordPress user. Pass that user with WP-CLI's own --user flag. Without it, the key stays bound to the user it is bound to now; if no user is bound yet, the command stops and asks for one.
Options
| Flag | Values | Notes |
|---|---|---|
--user=<user> | Login, email or ID | The WordPress user the new key acts as. Every tool call made with the key is checked against this user's capabilities. |
--porcelain | flag | Print only the new key, nothing else. For scripts that capture standard output. |
--yes | flag | Skip the "the current key will stop working immediately" confirmation. |
Example: rotate and store the key in one step
The key is printed once. Capture it straight into the place it will live, rather than into a terminal scrollback.
NEW_KEY=$(wp royal-mcp rotate-api-key --user=agency-bot --porcelain --yes --path=/var/www/client-site)
printf '%s' "$NEW_KEY" | your-secrets-tool put client-site/royal-mcp-api-key
The previous key is gone the moment the command returns, for every client that used it, including your own. Have each client's config ready to update before you rotate. The rotation is recorded in the Royal MCP Activity Log with the user it now acts as.
Create a WordPress user with only the capabilities your AI workflows need and pass it with --user. A key bound to an administrator can do everything an administrator can.
Running across many sites
The three commands are built to be looped. Two patterns cover most agency setups.
Morning health sweep
Print only the sites with a problem. --quiet drops the table; the exit code is what you want.
for site in /var/www/*/; do
wp royal-mcp connection-health --quiet --path="$site" \
|| echo "NEEDS ATTENTION: $(basename "$site")"
done
Quarterly key rotation
Rotate every site in one pass. Keep the user the same across sites so the capability review is done once.
for site in /var/www/*/; do
wp royal-mcp rotate-api-key --user=agency-bot --porcelain --yes --path="$site" \
| your-secrets-tool put "$(basename "$site")/royal-mcp-api-key"
done
Some managed hosts expose WP-CLI through their own command or an SSH alias. The royal-mcp subcommands work the same way; only the prefix changes.
Exit codes
| Command | 0 | 1 |
|---|---|---|
connection-health | No critical finding. | At least one check is critical. The count is printed as a warning. |
list-clients | Listed (an empty list is still success). | WP-CLI could not run the command (bad flag, unknown field). |
rotate-api-key | Key replaced and printed. | No user to bind to, confirmation declined, or the key could not be saved. The old key still works. |