InstaWP CLI in CI/CD and with AI Agents
Two things make the InstaWP CLI automatable: it authenticates from an environment variable, so no browser is needed, and every command accepts --json, so its output can be parsed.
Authenticate without a browser
Create an API token in the InstaWP dashboard (see API Overview), store it as a secret in your CI provider, and export it:
export INSTAWP_TOKEN=$YOUR_TOKENThe CLI picks it up automatically — no instawp login step required.
Per-pull-request preview sites
The most common pipeline: create a throwaway site when a PR opens, deploy the branch onto it, comment the URL, and delete the site when the PR closes.
export INSTAWP_TOKEN=${{ secrets.INSTAWP_TOKEN }}
# Create a site named after the PR, and capture the JSON result
instawp create --name "pr-$PR_NUMBER" --php 8.3 --json > site.json
# Deploy the build onto it
instawp sync push "pr-$PR_NUMBER" --path ./wp-content/
# Verify it came up
instawp wp "pr-$PR_NUMBER" option get siteurlAnd in the teardown job, when the PR closes:
instawp sites delete "pr-$PR_NUMBER" --forceGitHub Actions example
name: PR preview site
on:
pull_request:
types: [opened, synchronize, closed]
jobs:
preview:
if: github.event.action != 'closed'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
- run: npm install -g @instawp/cli@beta
- name: Create or update the preview site
env:
INSTAWP_TOKEN: ${{ secrets.INSTAWP_TOKEN }}
PR_NUMBER: ${{ github.event.number }}
run: |
instawp create --name "pr-$PR_NUMBER" --php 8.3 --json || true
instawp sync push "pr-$PR_NUMBER" --path ./wp-content/
instawp open "pr-$PR_NUMBER" --print
teardown:
if: github.event.action == 'closed'
runs-on: ubuntu-latest
steps:
- uses: actions/setup-node@v4
with:
node-version: 20
- run: npm install -g @instawp/cli@beta
- env:
INSTAWP_TOKEN: ${{ secrets.INSTAWP_TOKEN }}
PR_NUMBER: ${{ github.event.number }}
run: instawp sites delete "pr-$PR_NUMBER" --forceUse --temporary on create if you want the site to expire on its own as a safety net, in case a teardown job never runs.
Working with JSON output
--json turns any command into a data source. Pipe it into jq and use the values in later steps:
SITE_URL=$(instawp create --name "pr-$PR_NUMBER" --php 8.3 --json | jq -r '.data.url')
echo "Preview: $SITE_URL"instawp sites list --all --json | jq -r '.data[] | select(.status=="active") | .name'Safe automated changes
When a pipeline touches a real site rather than a throwaway one, take a version first so you can roll back:
instawp versions create prod-staging --name "pre-deploy"
instawp sync push prod-staging --path ./wp-content/
# if something is wrong:
instawp versions restore prod-stagingdb push takes a remote backup automatically before overwriting — do not disable that with --no-backup in an automated job.
AI coding agents
AI agents need a CLI, not a UI: every step has to be a shell command with parseable output. That is exactly what this tool is, which is why it works with Claude Code, Cursor, Codex, and similar assistants out of the box.
To let an agent drive InstaWP:
- Install the CLI in the agent's environment:
npm install -g @instawp/cli@beta - Provide the token as an environment variable:
INSTAWP_TOKEN=… - Tell the agent to prefer
--jsonso it can read the results reliably.
A typical agent loop looks like this:
instawp create --name agent-sandbox --php 8.3 --temporary --json
instawp wp agent-sandbox plugin install woocommerce --activate
instawp wp agent-sandbox -- post list --post_type=page --format=json
instawp logs agent-sandbox --php -n 100
instawp sites delete agent-sandbox --forceBecause the sites are real, hosted WordPress installs, the agent can test against genuine plugin behaviour instead of a mock — and because they are disposable, a bad run costs nothing.
TIP
If you want an AI assistant to talk to a WordPress site directly rather than through the shell, InstaWP also supports MCP — see Connect AI Assistants to your WordPress site using MCP.