← Back to Home

WordPress 7.1 + MCP Adapter for Content Sites

WordPressMCPAbilities APIAI automationWP-CLI

I actually run a content site with more than 600 published posts, and the most repetitive part of my week is digging out old drafts, rewriting meta descriptions, adding internal links and re-tagging. I used two weeks to wire the official MCP Adapter into that site, and for the first time I can let Claude Code and Cursor read and write content inside the chat instead of writing a throwaway REST script for every small request. This post is the whole thing: the commands you can copy, the mistakes I made, and how to scope permissions so it is safe in production.

⏳ TL;DR

The conclusion in three lines

Two desk items that help (with the reasoning further down)

👉 Check the Dell U2723QE on Amazon >>

👉 Check the BenQ ScreenBar Halo 2 on Amazon >>

Affiliate disclosure: both links above are Amazon affiliate links. If you buy through them I earn a small commission at no extra cost to you, and the price you pay is identical. I am not employed by or acting for either brand.

Why the Abilities API, not another pile of REST scripts

WordPress 6.9 introduced the Abilities API, which standardizes what a site can do into discoverable, typed and executable units called abilities. Every ability is registered with three things: a unique namespace/ability-name, typed input and output schemas, and a permission_callback. Once registered, the same ability is callable from PHP, from JavaScript and over the REST API. Core ships three read-only abilities to start with: core/get-site-info, core/get-user-info and core/get-environment-info.

Two directions get confused constantly, so keep them apart:

WordPress 7.1 “Mary Lou” (released 19 August 2026) turned the Abilities API from infrastructure into a toolkit. It added four filters: wp_pre_execute_ability to short-circuit the whole execution pipeline, wp_ability_normalize_input to transform input before validation, wp_ability_permission_result to modify or override permission results, and wp_ability_execute_result to transform or recover a result before output validation. It also introduced WP_Filter_Sentinel, which lets core tell “the default value was not changed” apart from “the caller explicitly passed this value”. That layer is exactly where protocol adapters, authorization layers and automation systems want to hook in.

One warning before you start: the older Automattic/wordpress-mcp repository was archived on 19 January 2026, its last release was v0.2.5 in July 2025, and it will not receive fixes. In 2026, build on the official WordPress/mcp-adapter project instead.

Prerequisites and version check

ComponentMinimumWhat I ran, and why
WordPress6.9 (where the Abilities API landed)7.1.2 (security release, 22 September 2026, fixing an unauthenticated path traversal in page template resolution that can lead to conditional RCE — CVE-2026-87902 / GHSA-7hp8-65ch-5whp)
PHP7.48.2 or newer is safer; the adapter needs ext-json
MCP Adapterv0.5.00.6.1 (13 August 2026; 0.6.0 on 12 August fixed protocol compatibility, resource metadata handling and session reliability)
WP-CLI2.x2.12.0 (current stable)
Node.js18 or newerRequired for the HTTP transport via `@automattic/mcp-wordpress-remote`
AuthenticationApplication PasswordRequires HTTPS; use a dedicated least-privilege user

Run these three checks before touching anything:

wp core version
wp --info | head -3
php -m | grep -i json

There is one trap worth knowing up front: the MCP Adapter is **not** in the WordPress.org plugin directory. Query the plugin API for the mcp-adapter slug and it returns “Plugin not found”, even though the bundled readme tells you to search for it under Plugins, Add New. The practical consequence is that the documented Requires Plugins: mcp-adapter header only resolves for plugins hosted on WordPress.org, so you cannot rely on WordPress to load the adapter for you.

Step 1: Install the adapter with one WP-CLI command

wp plugin install https://github.com/WordPress/mcp-adapter/releases/latest/download/mcp-adapter.zip --activate
wp plugin list --name=mcp-adapter

On activation the plugin registers a default server called mcp-adapter-default-server with this HTTP endpoint:

https://example.com/wp-json/mcp/mcp-adapter-default-server

It also exposes three meta tools that give an agent a layered way in: mcp-adapter-discover-abilities, mcp-adapter-get-ability-info and mcp-adapter-execute-ability.

Step 2: Expose the core abilities to the default server

Core’s own abilities stay invisible to that server until they are explicitly marked public for MCP. A filter is cleaner than editing core. Save the snippet below as wp-content/plugins/tp-enable-core-abilities/tp-enable-core-abilities.php, and **add the standard PHP opening tag at the top of the file** — only the function body is shown here so the angle brackets do not confuse the page rendering:

add_filter( 'wp_register_ability_args', 'tp_enable_core_abilities_mcp', 10, 2 );

function tp_enable_core_abilities_mcp( array $args, string $ability_name ) {
    $core = array( 'core/get-site-info', 'core/get-user-info', 'core/get-environment-info' );
    if ( in_array( $ability_name, $core, true ) ) {
        $args['meta']['mcp']['public'] = true;
    }
    return $args;
}

Then activate it and verify:

wp plugin activate tp-enable-core-abilities
curl -s -X POST -u 'mcp-bot:xxxx xxxx xxxx xxxx' \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","method":"tools/list","id":1}' \
  https://example.com/wp-json/mcp/mcp-adapter-default-server

All three core names should now come back as tools. If you register a custom server yourself and expose abilities explicitly through mcp_adapter_init, you do not need the public flag at all.

Step 3: Create a dedicated, least-privilege user and an application password

Do not connect an AI client as an administrator. To WordPress, an MCP client is just a logged-in user, and it can do everything that user can do.

wp user create mcp-bot mcp-bot@example.com --role=author --user_pass="$(openssl rand -base64 24)"
wp user get mcp-bot --field=roles

Next, go to Users → Profile → Application Passwords and create one. Two details matter: name it after the client (for example claude-code-laptop) so you can revoke exactly that credential later, and copy it immediately, because WordPress shows it once and stores only a hash. Verify the credential over REST before wiring up a client:

curl -s -u 'mcp-bot:xxxx xxxx xxxx xxxx' https://example.com/wp-json/wp/v2/users/me | head -c 300

A user object back means the authentication chain works. A 401 sends you straight to the error list below.

Step 4: Connect Claude Code and Cursor over HTTP

HTTP transport is the most portable option. For Claude Code, drop this in .mcp.json in your project directory, or in .claude.json in your home directory to make it global:

{
  "mcpServers": {
    "techpassive-wp": {
      "command": "npx",
      "args": ["-y", "@automattic/mcp-wordpress-remote@latest"],
      "env": {
        "WP_API_URL": "https://example.com/wp-json/mcp/mcp-adapter-default-server",
        "WP_API_USERNAME": "mcp-bot",
        "WP_API_PASSWORD": "xxxx xxxx xxxx xxxx"
      }
    }
  }
}

Cursor uses Settings → Tools and MCP → Add Custom MCP and writes to mcp.json, with an identical shape. VS Code takes the same structure, with one difference: the outer key is servers, not mcpServers. Claude Desktop uses Settings → Developer → Edit config, and you must **fully quit and relaunch** afterwards, because it only reads the config file at startup.

If the WordPress site sits on the same machine, switch to the STDIO transport. It needs neither an application password nor a public endpoint:

{
  "mcpServers": {
    "techpassive-wp": {
      "command": "wp",
      "args": ["--path=/var/www/html", "mcp-adapter", "serve", "--server=mcp-adapter-default-server", "--user=mcp-bot"]
    }
  }
}

The --user flag decides what the agent is allowed to do. In STDIO mode it is the only permission boundary, so do not casually write admin there.

Locking it down: three categories to keep private

When you write permission_callback, check the smallest capability that works: read for reading, edit_posts for editing content, manage_options for site configuration. Never use __return_true for convenience. In production, use a dedicated user, serve everything over HTTPS, prefer read-only, and log MCP activity. Keep a human approval step for anything destructive rather than running it as a hands-off autopilot.

Rollback: back to normal in three seconds

Any time you open a permission boundary, leave yourself an exit. Here it is two commands:

wp plugin deactivate tp-enable-core-abilities   # core abilities disappear from the default server
wp plugin deactivate mcp-adapter                # the whole MCP entry point goes away

For a harder stop, revoke the claude-code-laptop application password under Users → Profile → Application Passwords. The credential dies immediately and nothing needs restarting. That is the useful property of this setup: the AI side never sees a deletion, you simply close a door.

💣 Five real errors and how to fix them

Error 1: 401 Unauthorized even though the password is correct

**Symptom**: curl -u returns 401, and the MCP client’s tools/list comes back empty.

**Cause**: Apache or FastCGI strips the Authorization header before it ever reaches WordPress. This is the classic “authentication failure that is not an authentication problem”.

**Fix**: add this to the site’s root .htaccess:

RewriteEngine On
RewriteCond %{HTTP:Authorization} ^(.*)
RewriteRule .* - [E=HTTP_AUTHORIZATION:%1]

Two smaller traps in the same family: the spaces inside an application password are normal, so do not strip them, and the username must be the account that generated that specific password.

Error 2: tools/list returns only the three meta tools

Symptom: the connection works, but the client reports only three tools.

**Cause**: core abilities are not exposed through the default server unless marked public, and on 0.6.x the relationship between meta.public and meta.mcp.public changed. On 0.6.0 the adapter started exposing abilities carrying meta.public unless meta.mcp.public opts out, which makes the filter documentation the belt-and-braces route rather than the only route.

**Fix**: turn on meta.mcp.public with the filter from Step 2, then confirm the ability names you see carry the right prefix (core/). With a custom server that exposes abilities explicitly, the flag is unnecessary.

Error 3: there is no Application Passwords section on the profile screen

Symptom: the panel a tutorial told you to use simply does not exist.

Cause: application passwords are only available to HTTP requests when WordPress detects HTTPS. A plain-http local site, or a security plugin that disables the feature, hides the whole section.

Fix: install a trusted certificate and serve the site over HTTPS rather than working around the check, because the credential is sent on every request. For local development, use the STDIO transport instead and skip application passwords entirely.

Error 4: CERT_HAS_EXPIRED or fetch failed in the client

Symptom: the server sits greyed out in Claude Desktop and the logs show a TLS certificate error.

**Cause**: the mcp-remote proxy used by HTTP transport validates TLS certificates, so self-signed or expired certificates fail outright.

**Fix**: use a valid certificate such as Let’s Encrypt, or plain http:// for a local-only site. Never set something like NODE_TLS_REJECT_UNAUTHORIZED=0 on a production site.

Error 5: activating the 0.6.0 release ZIP white-screens the site

Symptom: activating the 0.6.0 release ZIP produces a fatal error.

**Cause**: the 0.6.0 ZIP shipped an autoloader class map pointing at files the ZIP omits. Any plugin calling class_exists('WP_CLI') on a normal web request could hit an uncaught fatal error. Installations built from source or through Composer were unaffected.

Fix: use 0.6.1 (released 13 August 2026), which repaired the release ZIP with no API, hook or protocol change. That is exactly why I pin 0.6.1 rather than 0.6.0.

Desk setup for long AI sessions (affiliate links)

Once the AI is inside the content workflow, I actually spend more time looking at a screen, not less: diffs and logs on one side, the editor on the other, and the client running in between. Two items did the most for me, and they are the ones in the TL;DR.

Dell UltraSharp U2723QE (27-inch 4K USB-C hub monitor): a single USB-C cable powers the laptop, carries 4K video and provides wired networking over RJ45, and the built-in KVM lets two machines share one keyboard and mouse. For long posts and diffs, 4K vertical space is measurable efficiency. Around $429–529, and prices move, so check the product page. The built-in speakers are effectively unusable, and the USB-C power delivery is not enough for a high-end gaming laptop.

BenQ ScreenBar Halo 2 (monitor light bar): a three-zone backlight with a wireless dial. When you are staring at a terminal and a diff at night, raising ambient light is kinder than cranking screen brightness. Around $179–199. Note that in auto-dimming mode the colour temperature locks to 4000K, which some readers find too cool, and the 5V/1A USB port on older monitors may not drive it, in which case you need an external 5V/3A supply.

Both links again are Amazon affiliate links. The price you pay is the same, and the commission helps me keep this series going.

FAQ

Q: Do I need WordPress 7.0 or 7.1?

A: No. The floor is 6.9, because that is where the Abilities API landed in core. That said, 7.1.2 patches a critical unauthenticated path traversal, so a new site should go straight to 7.1.2.

Q: Does MCP replace the REST API?

A: No, and it is not a replacement story. Most WordPress MCP servers call the REST API under the hood. MCP is a structured interface layer on top of it, built for AI agents that need to discover tools and understand their inputs without you pre-writing every call.

Q: Can I give the AI write access so it edits content automatically?

A: Yes, with four conditions: a dedicated least-privilege user, a revocable application password, HTTPS everywhere, and only the abilities you actually need exposed. Keep human approval for destructive actions instead of running it unattended.

Q: Does a local site need an application password?

A: No. With the WP-CLI STDIO transport (wp mcp-adapter serve) you need neither an application password nor a public endpoint, and the --user flag is the permission boundary.

Q: What about a site hosted on WordPress.com?

A: WordPress.com provides an MCP server on all paid plans, and free sites get access for the first 30 days after creation. No adapter installation is required.

Wrapping up and further reading

One line to take away: the Abilities API standardizes what your site can do, the MCP Adapter hands that to the AI, and permission scoping is what makes the whole thing safe enough to run in production. Wire up those three steps and your content site stops being a dashboard you click through by hand and becomes a control panel you can talk to.

Related posts from this series, all from the same 600-post site:

👉 Join MiniMax Token Plan: AI coding acceleration for businesses

👉 Join Xiaomi MiMo Platform: Leading AI model platform with cost-effective inference

👉 Join Aliyun AI: Top AI products with exclusive coupons for business innovation

📌 This article was AI-assisted generated and human-reviewed | TechPassive — An AI-driven content testing site focused on real tool reviews

🔗 Recommended Tools

These are carefully selected tools. Using our affiliate links supports us to keep producing quality content:

☁️ DigitalOcean Cloud ⚡ Vultr VPS ⭐ MiniMax Token Plan 🤖 QoderWork CN (Refer & Earn) ☁️ Aliyun AI Products 📚 WordPress Books 🔍 WordPress SEO Books 🌐 Web Hosting Books 🐳 Docker Books 🐧 Linux Books 🐍 Python Books 💰 Affiliate Marketing 💵 Passive Income Books 🖥️ Server Books ☁️ Cloud Computing Books 🚀 DevOps Books 🤖 Xiaomi MiMo Platform
Redis, object cache
WP-CLI, Internal Links
WP-CLI, 内链优化
Redis, 对象缓存
← Back to Home