mcpField
W
wp-cli

wp-cli

github.com/johnieCloud & DevOps267 installsUpdated 8w ago
Repository

About wp-cli

wp-cli is a skill for operating WordPress from the command line, suited to scripted, bulk, and remote administration. Inspection and database exports can run directly; mutating operations require confirmation.

Key features

  1. 01Manage databases, core, plugins, and themes
  2. 02Work with users, posts, options, and cache
  3. 03Run remotely through SSH or aliases
  4. 04Require confirmation for changes
  5. 05Guides for migrations, maintenance, and imports

Use cases

  1. 01Preview plugin updates before applying them
  2. 02Back up a database and migrate a site
  3. 03Import post content from CSV
  4. 04Audit users or manage a multisite installation

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/johnie/skills --skill wp-cli

After installing, type/wp-cliin Claude Code to confirm it loaded.

Bundled files

References and scripts installed along with SKILL.md.

evals/
trigger-set.json
references/
commands.md
examples-content.md
examples-maintenance.md
examples-migration.md
examples-multisite.md
examples-users.md

Details

From the project README

wp-cli

Terminal-first WordPress operations. Safer than wp-admin for bulk work, scriptable, SSH-friendly, and won't time out on 10k-row updates.

Only inspection commands and wp db export (which takes a backup) run without a prompt. Every mutating command — search-replace, db import, db reset, plugin/theme installs, user and post writes — prompts before it runs. That friction is deliberate: this skill routinely points at production.

Reference files live in ${CLAUDE_SKILL_DIR}/references/.

When NOT to use

  • One-off edits a content editor would do in 10 seconds in the admin UI. CLI is overkill and error-prone for single-row clicks.
  • Data transformations that span millions of rows — WP's ORM will be slow; consider a direct SQL migration with an explicit transaction.
  • Anything that needs to run inside a WordPress plugin's hook lifecycle (e.g., REST validation, custom post type registration) — that's PHP code, not CLI.
  • Destructive commands without a current backup. wp db reset, wp db clean, bulk deletes — always snapshot first.

Preflight

Always verify before doing anything:

wp --version                  # wp-cli is installed
wp core is-installed          # WordPress is actually set up at this path
wp core version               # which WP version

If not at the WordPress root, pass --path=/path/to/wordpress or cd there first. On remote hosts, use --ssh=user@host/path or a configured alias (see Remote Execution).

Safety patterns

Backup before destructive work
# Database snapshot
wp db export backup-$(date +%Y%m%d-%H%M%S).sql

# Full site snapshot (db + content)
tar -czf site-backup-$(date +%Y%m%d-%H%M%S).tar.gz wp-content/ backup-*.sql
Dry-run when available
wp plugin update --all --dry-run
wp search-replace 'old.com' 'new.com' --dry-run
Dangerous commands — confirm explicitly

These are irreversible without a backup. Confirm with the user before running:

  • wp db reset — drops every table
  • wp db clean — drops every table matching the current $table_prefix
  • wp site delete (multisite) — removes a site and its content
  • wp user delete without --reassign — orphans the user's posts (they get deleted too). Always pass --reassign=<new_author_id> to reassign their content first. The flag exists because orphaning content is almost never what you want — the user's posts are the institutional record, not the user row.
  • wp post delete $(wp post list --format=ids) and similar bulk-delete pipes — quietly turn the whole site into a blank page if the filter is wrong.

Performance flags

--format=json              # machine-readable
--format=csv               # spreadsheet import
--format=ids               # space-separated IDs, for piping
--fields=ID,post_title     # return only what you need
--skip-plugins             # bypass plugin load (fast, may break plugin-dependent commands)
--skip-themes              # bypass theme load
--quiet                    # suppress info output

--skip-plugins is a scalpel: it makes wp db export instant, but breaks commands that rely on a plugin's hooks (e.g., ACF exporters, custom taxonomies registered by a plugin).

Command catalog

Full flag docs and gotchas are in references/commands.md. Categories:

CategoryPrefixTypical use
Databasewp dbexport, import, query, optimize, search-replace
Corewp coreinstall, update, verify-checksums, version
Pluginswp pluginlist, install, activate, update, delete
Themeswp themelist, install, activate, update, delete, theme mod
Userswp usercreate, list, delete (--reassign), update, roles, generate
Posts / Pageswp postlist, create, update, delete, generate, post term
Commentswp commentlist, approve, spam, trash, delete
Optionswp optionget, update, delete, list, pluck/patch for nested values
Cachewp cache / wp transientflush, delete, set, list
Cronwp cronevent list/run/schedule/delete, cron test
Configwp configcreate, get, set, shuffle-salts
Multisitewp sitelist, create, delete, empty, activate/archive

Workflows

Full step-by-step workflows live in references/, split by task — load only the one the user is doing end-to-end:

WorkflowFile
Site migration (local → prod) + search-replacereferences/examples-migration.md
Plugin updates with rollback, debugging, DB maintenancereferences/examples-maintenance.md
User audit, cleanup, safe password rotationreferences/examples-users.md
Bulk content import from CSVreferences/examples-content.md
Multisite / network operationsreferences/examples-multisite.md

Remote execution

Ad-hoc SSH
ssh [email protected] "cd /var/www/html && wp plugin list"
Configured aliases (preferred)

Define aliases once in ~/.wp-cli/config.yml:

@prod:
  ssh: [email protected]/var/www/html
@staging:
  ssh: [email protected]/var/www/staging

Then:

wp @prod plugin list
wp @staging db export

Aliases beat ad-hoc SSH because they compose with every wp-cli flag (wp @prod --dry-run search-replace ...) and don't invite shell-quoting bugs.

Common errors

ErrorCauseFix
The site you have requested is not installedNot at WordPress root / wp-config.php missingcd to root or --path=/path/to/wordpress
MySQL connection failedBad credentials or MySQL downCheck wp-config.php, confirm MySQL is running
Error: Can't select databaseDB doesn't existwp db create
PHP Fatal error: Allowed memory size exhaustedLarge op or heavy pluginsphp -d memory_limit=512M $(which wp) db export
This does not seem to be a WordPress installationWP files not foundCheck directory; confirm WP is actually installed
The \guid` column is often used ... but should not be updated`Expected warning--skip-columns=guid suppresses it; GUIDs are permanent IDs, not URLs

Antipatterns — when wp-cli is the wrong tool

  • Looping over millions of rows in shell with xargs or for. Each wp invocation bootstraps WordPress; 1M iterations = days. Prefer a single wp db query with a proper SQL statement, or a PHP-side batched job.
  • Using wp search-replace without --precise on serialized data larger than a hobby blog. --precise is slower but handles PHP serialized strings correctly; without it, serialized arrays silently corrupt.
  • Validation and domain logic. If the logic belongs inside a WP plugin's hook lifecycle, do it there. wp-cli is for operational work, not business rules.
  • Credential-bearing commands in your shell history. wp user create with --user_pass=... leaks. Pipe the password in or let wp-cli prompt.

Best practices

  1. Staging first, always. Never run an untested command on production.
  2. Track wp-config.php changes in version control when feasible (exclude secrets).
  3. Read the output. wp-cli warnings often precede data loss.
  4. Document non-obvious workflows — migrations, multisite conversions — as they happen; future-you will not remember which flags you used.
  5. --format=json whenever piping to jq or another script. The default human format rots.
  6. Verify after big changes — load the homepage, check admin, exercise critical paths.
  7. Keep wp-cli current: wp cli update (Phar installs only — Homebrew and Composer installs update through their package manager).

References

Comments

Markdown supported