Rust-native CLI for managing WordPress sites remotely via the REST API. Inspired by WP-CLI, but built from the ground up for AI agents -- because agents shouldn't need PHP installed to manage a WordPress site.
WP-CLI requires a local PHP runtime, a bootstrapped WordPress installation, and SSH access to run. That's fine for humans on a server, but it's a non-starter for AI coding agents like Claude, Cursor, or Codex that operate remotely over HTTPS. wpx solves this by communicating purely via the WordPress REST API as a single static binary with zero runtime dependencies.
Designed agent-first: structured JSON output, schema introspection, and semantic exit codes let AI agents operate WordPress programmatically. Designed human-friendly: auto-detecting table output, colored terminals, and shell completions make it pleasant for interactive use.
- Full WordPress REST API coverage -- 34 command groups spanning posts, pages, media, users, plugins, themes, menus, widgets, blocks, and more
- Structured output -- JSON, Table, CSV, YAML, and NDJSON formats with automatic TTY detection
- Schema introspection --
wpx schema <command>emits JSON Schema for any command's input/output - Semantic exit codes -- 11 distinct codes (0-10) so agents can programmatically decide retry/abort/fix strategies
- Multi-site fleet management -- run commands across dozens of sites concurrently with
wpx fleet exec - Application Passwords & OAuth 2.1 -- secure authentication without exposing wp-admin credentials
- Field masking --
--fields id,title,statusto reduce payload size for agent consumption - Automatic pagination --
--all-pagesstreams every result as NDJSON - Site discovery --
wpx discover <url>probes a site's REST API capabilities - Dry-run mode --
--dry-runpreviews destructive operations before executing
Homebrew (macOS/Linux):
brew tap osodevops/wpx
brew install osodevops/tap/wordpress-cliCargo (from source):
cargo install --git https://github.com/osodevops/wordpress-cli wpx-cliBinary download -- grab the latest release for your platform from the Releases page.
wpx auth set --site production --username admin --password "xxxx xxxx xxxx xxxx"Credentials are stored in ~/.config/wpx/credentials.toml with restricted file permissions.
wpx auth test --site production# List recent posts (human-readable table in terminal)
wpx post list --site production
# Same command, but pipe to jq (auto-switches to JSON)
wpx post list --site production | jq '.[0].title'
# List plugins as JSON
wpx plugin list --site production --output json
# Create a draft post
wpx post create --site production --title "Hello from wpx" --status draft
# Global search
wpx search "migration guide" --site production| Command | Description | Subcommands |
|---|---|---|
post |
Manage posts | list, get, create, update, delete, search |
page |
Manage pages | list, get, create, update, delete |
media |
Manage media attachments | list, get, update, delete |
comment |
Manage comments | list, get, create, update, delete |
block |
Manage reusable blocks | list, get, create, update, delete, search, render |
search |
Global search across content | (direct command -- takes a query argument) |
| Command | Description | Subcommands |
|---|---|---|
category |
Manage categories | list, get, create, update, delete |
tag |
Manage tags | list, get, create, update, delete |
taxonomy |
List and inspect taxonomies | list, get |
| Command | Description | Subcommands |
|---|---|---|
user |
Manage users | list, get, me, create, update, delete |
| Command | Description | Subcommands |
|---|---|---|
plugin |
Manage plugins | list, get, install, activate, deactivate, update, delete, status |
theme |
Manage themes | list, get, activate, delete, status |
settings |
Manage site settings | list, get, set |
option |
Alias for settings |
list, get, set |
| Command | Description | Subcommands |
|---|---|---|
block-type |
List and inspect block types | list, get |
block-pattern |
List block patterns | list |
block-pattern-category |
List block pattern categories | list |
| Command | Description | Subcommands |
|---|---|---|
menu |
Manage navigation menus | list, get, create, update, delete |
menu-item |
Manage menu items | list, get, create, update, delete |
menu-location |
List and inspect menu locations | list, get |
widget |
Manage widgets | list, get, create, update, delete |
widget-type |
List and inspect widget types | list, get |
sidebar |
List and inspect sidebars | list, get |
| Command | Description | Subcommands |
|---|---|---|
post-type |
List and inspect post types | list, get |
post-status |
List and inspect post statuses | list, get |
discover |
Probe a site's REST API capabilities | (direct command -- takes a URL argument) |
schema |
Show JSON Schema for a command | (direct command -- takes a command path) |
| Command | Description | Subcommands |
|---|---|---|
fleet |
Run commands across multiple sites | exec, status |
auth |
Manage authentication | set, test, list, logout, oauth |
info |
Show version, sites, capabilities | (direct command) |
version |
Show version information | (direct command) |
completions |
Generate shell completions | (direct command -- takes a shell argument) |
| Flag | Env Var | Default | Description |
|---|---|---|---|
--site <name> |
WPX_SITE |
default |
Target site profile name |
--url <url> |
WPX_URL |
-- | Direct URL override (skips profile lookup) |
--output <fmt> |
WPX_OUTPUT |
auto |
Output format: json, table, csv, yaml, ndjson, auto |
--fields <f1,f2> |
-- | -- | Comma-separated field mask to reduce output |
--no-color |
NO_COLOR |
-- | Disable colored output |
--no-prompt |
WPX_NO_PROMPT |
-- | Disable all interactive prompts |
--quiet |
-- | -- | Suppress non-essential output |
--verbose |
-- | -- | Enable debug logging to stderr |
--timeout <secs> |
WPX_TIMEOUT |
30 |
Request timeout in seconds |
--retries <n> |
WPX_RETRIES |
3 |
Retry count for failed requests |
--dry-run |
-- | -- | Show what would be done without executing |
--confirm |
-- | -- | Skip confirmation prompts for destructive actions |
--all-pages |
-- | -- | Fetch all pages and stream results (forces NDJSON) |
- User-level:
~/.config/wpx/config.toml - Project-level:
./.wpx.toml(checked in to your repo for team defaults) - Credentials:
~/.config/wpx/credentials.toml(never commit this)
Example config.toml:
[default]
output = "json"
timeout = 60
retries = 5
[sites.production]
url = "https://example.com"
auth = "application-password"
username = "admin"
[sites.staging]
url = "https://staging.example.com"
auth = "application-password"
username = "editor"| Variable | Description |
|---|---|
WPX_SITE |
Default site profile name |
WPX_URL |
Direct WordPress URL (bypasses profile lookup) |
WPX_OUTPUT |
Default output format |
WPX_TIMEOUT |
Request timeout in seconds |
WPX_RETRIES |
Retry count for failed requests |
WPX_NO_PROMPT |
Disable interactive prompts |
NO_COLOR |
Disable colored output (standard convention) |
CLI flags > env vars > project config (.wpx.toml) > user config (~/.config/wpx/config.toml) > defaults
WordPress 5.6+ supports Application Passwords natively. No plugins required.
- Log in to wp-admin and navigate to Users > Profile
- Scroll to Application Passwords
- Enter a name (e.g., "wpx CLI") and click Add New Application Password
- Copy the generated password (spaces are fine -- wpx strips them)
- Store it with wpx:
wpx auth set --site production --username admin --password "XXXX XXXX XXXX XXXX"For environments that require OAuth (headless WordPress, enterprise SSO):
wpx auth oauth \
--site production \
--client-id "your-client-id" \
--authorize-url "https://example.com/oauth/authorize" \
--token-url "https://example.com/oauth/token"This opens a browser for the authorization code flow with PKCE, then stores the resulting token.
wpx supports six output formats. By default (--output auto), it renders tables when stdout is a TTY and JSON when piped.
| Format | Flag | Description |
|---|---|---|
| Auto | --output auto |
Table if TTY, JSON if piped |
| JSON | --output json |
Pretty-printed JSON |
| Table | --output table |
ASCII table for human reading |
| CSV | --output csv |
Comma-separated values |
| YAML | --output yaml |
YAML format |
| NDJSON | --output ndjson |
Newline-delimited JSON (one object per line) |
# Interactive terminal: auto-renders a table
wpx post list --site production
# Piped to another program: auto-switches to JSON
wpx post list --site production | jq '.[] | .title'
# Force a specific format
wpx plugin list --site production --output csv > plugins.csvRun commands across multiple WordPress sites concurrently:
# Check plugin status across all configured sites
wpx fleet exec "plugin list" --sites "production,staging,dev"
# Update a plugin everywhere (with concurrency limit)
wpx fleet exec "plugin update --slug akismet" --concurrency 3
# Check fleet health
wpx fleet statusEvery wpx command returns a semantic exit code that agents can use for programmatic error handling:
| Code | Name | Description |
|---|---|---|
0 |
Success | Command completed successfully |
1 |
General Error | Unclassified error |
2 |
Invalid Args | Bad CLI arguments or configuration |
3 |
Auth Failure | Authentication failed (bad credentials, expired token) |
4 |
Not Found | Requested resource does not exist |
5 |
Permission Denied | Authenticated but not authorized |
6 |
Rate Limited | Too many requests (check retry_after_secs in error JSON) |
7 |
Network Error | DNS, TLS, or connection failure |
8 |
Server Error | WordPress returned HTTP 5xx |
9 |
Conflict | Resource conflict (e.g., duplicate slug) |
10 |
Validation Error | Invalid field value (check field in error JSON) |
Errors are emitted as structured JSON on stderr:
{
"error": true,
"message": "Resource not found: post 99",
"exit_code": 4,
"resource": "post",
"id": "99",
"suggestion": "Use 'wpx post list' to find valid IDs"
}Agents can discover the input/output shape of any command at runtime:
# Show schema for a specific command
wpx schema post list
# List all available schemas
wpx schemawpx binary (6 crates)
├── wpx-cli CLI parsing (clap), command dispatch, shell completions
├── wpx-core Resource trait, domain types, semantic exit codes
├── wpx-api HTTP client (reqwest + rustls), retry, pagination
├── wpx-auth Application Passwords, OAuth 2.1 (PKCE)
├── wpx-config TOML config, site profiles, credential store
└── wpx-output JSON, Table, CSV, YAML, NDJSON rendering
All crates share a workspace version (0.1.0) and are published together.
# Clone
git clone https://github.com/osodevops/wordpress-cli.git
cd wordpress-cli
# Build
cargo build --release
# Run tests
cargo test --workspace
# Lint
cargo clippy --workspace -- -D warnings
# The binary is at target/release/wpx
./target/release/wpx --version# Bash
wpx completions bash > ~/.local/share/bash-completion/completions/wpx
# Zsh
wpx completions zsh > ~/.zfunc/_wpx
# Fish
wpx completions fish > ~/.config/fish/completions/wpx.fishLicensed under either of:
at your option.