Manage WordPress sites from the terminal with Claude Code

Publish posts, deploy snippets, and edit pages without ever opening wp-admin.

By on

Loading the Elevenlabs Text to Speech AudioNative Player...

We manage our client WordPress sites using Claude Code: publishing blog posts, deploying custom code snippets, uploading media, editing page content, and more, all from the terminal. No browser, no wp-admin clicking, no copy-pasting between tabs.

This guide focuses on the REST API approach, which handles most WordPress tasks. If you need deeper access (editing theme/plugin files or running WP-CLI), you can extend this setup by giving Claude Code SFTP access. But for everyday site management, the REST API approach is simpler and cleaner.

The core idea: WordPress has a built-in REST API. Claude Code has tools to run shell commands, read/write files, and fetch URLs. Connect the two with an application password and Claude Code can do almost anything you’d do in wp-admin, via script, on demand, fast.

The setup has three parts:

  1. Application passwords for API authentication
  2. A JSON file listing your sites and credentials
  3. A CLAUDE.md file teaching Claude Code how to work with your sites

Step 1: Create an Application Password

WordPress has supported application passwords natively since version 5.6. They let you authenticate REST API requests without exposing your main login credentials.

  1. Go to Users > Profile in wp-admin
  2. Scroll to Application Passwords
  3. Enter a name (e.g., “Claude Code”) and click Add New Application Password
  4. Copy the generated password (you won’t see it again)

The password will look something like aBcD eFgH iJkL mNoP qRsT uVwX (spaces included, which is normal).

Claude can now authenticate API requests with HTTP Basic Auth:

curl -u "username:aBcD eFgH iJkL mNoP qRsT uVwX" \
  https://yoursite.com/wp-json/wp/v2/posts

I recommend creating a dedicated user account (e.g., api@yourcompany.com) specifically for API access rather than using your personal account.

Step 2: Create a Sites JSON File

Create a wordpress-sites.json file in your project directory. This gives Claude Code structured access to all your site details in one place.

{
  "sites": [
    {
      "name": "My Site",
      "url": "https://www.example.com/",
      "credentials": {
        "username": "api@yourcompany.com",
        "application_password": "xxxx xxxx xxxx xxxx xxxx xxxx"
      },
      "theme": "Twenty Twenty-Five",
      "builder": "Gutenberg",
      "hosting": "SomeHostingCompany"
    },
    {
      "name": "Client Site",
      "url": "https://www.clientsite.com/",
      "credentials": {
        "username": "api@yourcompany.com",
        "application_password": "yyyy yyyy yyyy yyyy yyyy yyyy"
      },
      "theme": "Kadence",
      "builder": "Kadence Blocks",
      "hosting": "SomeHostingCompany",
      "custom_post_types": [
        {
          "name": "Projects",
          "slug": "project",
          "taxonomies": ["project-category"]
        }
      ],
      "notes": "Career posts use h3 headings for sections."
    }
  ]
}

A few tips on what to include:

Important: Add wordpress-sites.json to your .gitignore if your repo is public. These are real credentials.

Step 3: Write Your CLAUDE.md

The CLAUDE.md file is where you teach Claude Code how to work with your WordPress sites. Place it in your project root. Claude Code reads it automatically at the start of every conversation.

Here’s a starter template based on what we’ve learned managing sites in production:

# WordPress Site Management

WordPress site credentials and details are stored in `wordpress-sites.json`.

## WordPress API Requests

When sending JSON with special characters (quotes, em-dashes, apostrophes)
to the WordPress REST API, avoid using bash HEREDOCs as they cause quoting
issues. Instead:

1. Write the JSON to a temporary file using the Write tool
2. Use `curl -d @filename` to read from the file
3. Delete the temp file after the request completes

## Publishing Blog Posts

When publishing blog posts, do not include the featured image in the post
body. The theme automatically displays the featured image above the post
content, so including it in the body causes it to appear twice.

The CLAUDE.md is where you encode all the lessons you learn over time. Here are some real examples from our setup:

Handling Special Characters in API Requests

We learned that sending post content with curly quotes, em-dashes, or apostrophes through bash heredocs causes escaping nightmares. The fix: write the JSON payload to a temp file and use curl -d @file. This instruction in CLAUDE.md saved us from hitting this issue repeatedly.

Plugin-Specific Instructions

If you use plugins with REST API endpoints, document their quirks. For example, we use the Fluent Snippets plugin for deploying custom PHP/CSS/JS to sites. Its API has non-obvious behavior: snippets are always created as drafts regardless of the status you send, so you need a separate API call to publish them. That kind of knowledge belongs in CLAUDE.md.

Cache Purging

If your site uses a caching plugin, include the purge command so Claude Code clears the cache after making changes:

## Cache Purging

After deploying snippets or making frontend changes, purge the cache:
curl -u "user:pass" "https://site.com/?breeze_purge=1&breeze_action=breeze_purge_all"

Content Structure Conventions

If your sites follow specific content patterns, document them. We include Gutenberg block markup templates so Claude Code generates correctly structured content:

## Building with Gutenberg

Wrap all content in the Section pattern:

<!-- wp:group {"tagName":"section",...} -->
  <!-- wp:group {"metadata":{"name":"Section inner container"}} -->

    [CONTENT]

  <!-- /wp:group -->
<!-- /wp:group -->

What You Can Actually Do

Once this is set up, you can do things like:

All without opening a browser.

The Workflow in Practice

A typical interaction looks like this:

You: Publish this blog post to Shawn's site.
     Use this photo as the featured image. [attaches image]

Claude Code:
  1. Reads wordpress-sites.json to get Shawn's site credentials
  2. Resizes the image to 1200px wide, converts to WebP
  3. Uploads the image via /wp-json/wp/v2/media
  4. Writes the post content as Gutenberg blocks
  5. Creates the post via /wp-json/wp/v2/posts with the featured image set
  6. Returns the live URL

Since these tasks run in the background, Claude Code notification sounds let you step away and hear the moment Claude finishes or needs your approval.

Claude Code gets better at this over time, not because of memory, but because your CLAUDE.md accumulates the lessons. Every time you hit a quirk (escaping issues, plugin API gotchas, content formatting rules), you add it to CLAUDE.md and never hit it again.

Security Considerations

Getting Started Checklist

  1. Install Claude Code (npm install -g @anthropic-ai/claude-code)
  2. Create an application password in WordPress for a dedicated API user
  3. Create wordpress-sites.json with your site details
  4. Create a CLAUDE.md with API usage instructions
  5. Add wordpress-sites.json to .gitignore
  6. Start Claude Code in your project directory and try: “List the recent posts on [site name]”

That’s it. You now have a WordPress management setup that runs entirely from your terminal. As you use it, keep adding to your CLAUDE.md. That file is what makes the whole system work.