Tutorials

Here Are the Fixes We Made When Connecting a WordPress Site to AI Agents via MCP

MCP Adapter 0.6.1 tests reveal fixes for categories, schemas, write limits, and security checks before AI agents touch live WordPress sites.

Here Are the Fixes We Made When Connecting a WordPress Site to AI Agents via MCP

Key Takeaways

  • WordPress MCP Adapter exposes Abilities API entries as MCP tools, allowing AI agents to call site functions without accessing the admin interface.
  • A reliable setup requires registering the ability category first and using both public and show_in_rest metadata for WordPress 7.1 compatibility.
  • Read-only abilities need strict JSON Schema validation, permission checks, and an empty-object default to prevent failures when called with no arguments.
  • Write abilities should be narrowly scoped: require edit_posts permission, hard-code draft status, sanitize inputs, and reject unknown fields such as status: publish.
  • MCP annotations like readonly and idempotent are only hints; real safety depends on permissions, schema validation, and server-side enforcement.

Meta description: Test WordPress MCP Adapter 0.6.1 with Abilities API: two abilities, three failures, fixes, security notes, and what site owners should do next.

Here Are the Fixes We Made When Connecting a WordPress Site to AI Agents via MCP

Tags: WordPress MCP Adapter, Abilities API, AI agents, WordPress security, MCP tools

Featured image: abstract friendly illustration of WordPress blocks connected to an MCP tool bridge, no people, no logos, no text.

This guide is for WordPress developers and small-business site owners who want to let AI agents read or draft content without opening the whole admin screen. AnpsThemes, a WordPress theme studio that has worked with construction, logistics and industrial businesses since 2011, tested WordPress MCP Adapter 0.6.1 on WordPress 7.1.2, registered two abilities, connected them over the Model Context Protocol, and found three fixes that matter before an agent gets close to a live site. The studio disclosed that the article and the test plugin were written with help from the AI assistant Claude, and that every error message quoted here is real output from those tests.

What changed in WordPress for AI agents

W3Techs says more than 40% of all websites run on WordPress. Over the past year, that install base gained a more standard path for AI agents. WordPress 6.9 introduced the Abilities API, which lets a plugin or theme register a named unit of work, such as listing projects, with a description, a JSON Schema for inputs and outputs, a permission check, and the code that runs. WordPress validates input, checks permissions, and validates output. Registered abilities are also reachable through REST at /wp-abilities/v1.

WordPress 7.0 added the AI Client to core. That part works in the other direction: it lets PHP code call AI models through one provider-agnostic function, wp_ai_client_prompt(). The test did not need the AI Client because the goal was to expose site functions to an external agent, not to call a model from inside WordPress.

Here Are the Fixes We Made When Connecting a WordPress Site to AI Agents via MCP

The bridge is the official MCP Adapter plugin, available on GitHub or through Composer. It turns registered abilities into Model Context Protocol (MCP) tools that any MCP client can call. MCP is the protocol layer that lets an agent discover and invoke tools from a remote server. The adapter can serve those tools over STDIO through WP-CLI or over HTTP.

How the construction demo was built and broken

AnpsThemes built a small plugin for a fictional construction company, using a portfolio style that many of its customer sites use. It ran WordPress 7.1.2 with MCP Adapter 0.6.1 and created a project post type with five sample projects. Each project stored its service, town, and duration. Then it registered two abilities: contractor/list-projects, a read-only search of finished projects, and contractor/draft-project, a writer that could only create draft pages from job notes.

Instead of using a chat app, the test spoke MCP directly. It started the server with wp mcp-adapter serve and sent raw JSON-RPC messages, so the output showed exactly what an agent would receive. The first three surprises came from schema defaults, write limits, and the default MCP server design.

  1. Register the category before the ability. Every ability belongs to a category, and the category must be registered first on wp_abilities_api_categories_init with wp_register_ability_category. The demo used the contractor category with the label Contractor and the description Projects and services of a construction company.
  1. Make the read-only ability safe to call. The list-projects ability used wp_register_ability on wp_abilities_api_init. Its input schema allowed service as an enum of kitchen, bathroom, roofing, and basement, town as a string, and limit as an integer from 1 to 20 with a default of 5. additionalProperties: false rejects any field outside the schema. The output schema returned id, title, service, town, duration_weeks, and url. The permission callback required current_user_can('read'). Published projects are public anyway, but the agent still needed a logged-in user.

The meta block used public: true and show_in_rest: true. In WordPress 7.1, public exposes the ability to REST and MCP, while WordPress 7.0 still needs show_in_rest for REST, so the test set both. The description was written for a model, because a model reads it when choosing a tool.

The schema did real validation, and WordPress rejected bad input before the callback ran. A service of plumbing returned input[service] is not one of kitchen, bathroom, roofing, and basement. A limit of 50 returned input[limit] must be between 1 (inclusive) and 20 (inclusive). The first failure was more common: calling the tool with no arguments returned input is not of type object, because an empty input was not an object. The fix was to add 'default' => array() at the top level of the input schema. After that, a call with no arguments returned the five most recent projects.

Here Are the Fixes We Made When Connecting a WordPress Site to AI Agents via MCP
  1. Keep the write ability narrow. The draft-project ability required title, service, town, and summary. It accepted title length 5 to 120, town length at least 2, duration_weeks 1 to 104, and summary at least 40 characters. Its callback used wp_insert_post with post_status hard-coded to draft, sanitize_text_field on title and town, wp_kses_post on content, and meta for service, town, and duration_weeks. It returned id, status, and edit_url for a human to review and publish. The draft ability also used public: true and show_in_rest: true.

The permission callback allowed only users who can edit_posts. If not, it returned the WP_Error code contractor_cannot_draft and the message This account cannot create drafts. Connect with a user who can edit posts. The test tried to add "status": "publish" to the input. Because additionalProperties: false was set, WordPress refused with status is not a valid property of Object. Even without that line, nothing the agent sends reaches post_status.

  1. Remember annotations are hints, not armor. The meta block marked list-projects as readonly and idempotent, and draft-project as readonly false, destructive false, and idempotent false. Over REST, WordPress used those annotations to choose the HTTP method. Calling the read-only ability with POST returned 405 Read-only abilities require GET method. Calling the draft ability with GET returned 405 Abilities that perform updates require POST method. The MCP Adapter also passes them to clients as hints such as readOnlyHint.

But annotations do not enforce the callback. A read-only ability whose code deletes posts could still delete posts. The MCP specification says clients must treat annotations from untrusted servers as untrusted. The real protection is the permission callback and the code inside the ability.

  1. Replace the default MCP server with a focused one. The MCP Adapter creates a default server automatically. When asked for its tools, it did not show the two contractor abilities. It showed three generic tools: one to discover abilities, one to get an ability's details, and one to execute any ability by name. That keeps tool lists short on sites with many abilities, but it made the agent take three steps where one should do. It also stripped per-ability hints: the execute tool can run anything, so it is marked destructiveHint: true, and a harmless project search goes through the same tool as a write. A client that asks for confirmation before destructive actions cannot tell them apart.

The discovery tool also listed WordPress's own public abilities next to the contractor abilities, including one that returns PHP and database server details. WordPress only lets administrators run that one, which is another reason not to connect agents as an administrator.

The fix was to create a focused server through mcp_adapter_init. The demo called create_server with server ID contractor-server, REST namespace mcp, REST route contractor-server, name Contractor Site, description Read the project portfolio and draft new project pages., version 1.0.0, the transport class \WP\MCP\Transport\HttpTransport::class, the error handler \WP\MCP\Infrastructure\ErrorHandling\ErrorLogMcpErrorHandler::class, a null observability handler, and only contractor/list-projects and contractor/draft-project. With that server, the tool list showed the two chosen abilities as separate MCP tools.

Common mistakes

Site owners should not treat the Abilities API as an automatic safe gateway. The test shows three mistakes to avoid: leave off a top-level default when agents may call a tool with no arguments, expose writes without hard-coding the safest status, and rely on the default MCP server when a focused server would keep tools separate and reduce confusion. The practical next step for any WordPress site that wants agent access is to start with read-only abilities, use non-admin accounts, create a focused MCP server, and require human review for drafts.

Comments (0)

  1. No comments yet. Be the first to share what worked for you.

Leave a comment

Comments are reviewed before they appear. Your email address is not published.