If you run a WordPress site, there is a reasonable chance it already exposes a set of callable tools to AI agents — and that nobody made a decision to turn them on. Not because anything was installed carelessly, but because tool registration now arrives bundled inside ordinary plugins: an SEO plugin, an image optimiser, a store.
Rather than write that in the abstract, I audited a production site: this one. WordPress 7.0.2, WooCommerce 10.9.4, the usual plugin stack any commercial WordPress site accumulates. The numbers below come from that live install, not from release notes.
Forty-two abilities are registered. Thirty-one of them are flagged as public MCP tools. Nine of those can write. Four are marked destructive. None of that was a choice I made in a settings screen.
The useful part of this article is not the alarm — as you will see, the endpoints turned out to be properly authenticated, and the scarier headlines circulating about WooCommerce and MCP are overstated. The useful part is the method: a one-command audit any site owner can run, and a clear-eyed read of what actually changes the day you connect an agent.

What "MCP server" actually means on a WordPress site
Model Context Protocol is a standard way for an AI client — Claude, ChatGPT, an internal agent — to discover and call tools on a remote system. On WordPress the plumbing has three layers, and it helps to keep them separate:
- The Abilities API. WordPress 7.0 added
wp_register_ability()andwp_get_abilities()to core. An ability is a named, schema-described function: an input schema, an output schema, a permission callback, and metadata. It is a registry, nothing more. - The MCP adapter. A separate library that reads the abilities registry and republishes the eligible entries as MCP tools over an HTTP transport.
- The transport. The REST route an agent actually talks to.
The distinction matters because a registered ability is inert on its own. What promotes it to a callable tool is a flag in its own metadata — mcp.public — plus an adapter present to serve it. On the site I audited, both conditions are met 31 times.
I covered the Abilities API itself in more detail when WordPress 7.0 shipped, in WordPress 7.0 put AI in core — do you still need a chatbot plugin?. This article picks up where that one left off: not what core registers, but what your plugins publish.
The audit: 42 abilities, 31 exposed as tools
Here is the full breakdown by vendor, taken from wp_get_abilities() on the live site.
| Namespace | Abilities | Flagged as MCP tools | Can write | Marked destructive |
|---|---|---|---|---|
rank-math | 13 | 13 | 2 | 0 |
wpforms | 8 | 3 | 0 | 0 |
woocommerce | 7 | 7 | 4 | 3 |
imagify | 7 | 7 | 2 | 1 |
core | 3 | 0 | 0 | 0 |
mcp-adapter | 3 | 0 | 0 | 0 |
wp-mail-smtp | 1 | 1 | 0 | 0 |
| Total | 42 | 31 | 9 | 4 |
There is a second finding hiding in that table. The MCP adapter is not a plugin anyone installed. It arrives vendored — bundled as a dependency inside other plugins. On this install it ships three separate times:
wp-content/plugins/woocommerce/vendor/wordpress/mcp-adapterwp-content/plugins/seo-by-rank-math/vendor/wordpress/mcp-adapterwp-content/plugins/imagify/vendor/wordpress/mcp-adapter
An image optimiser shipped an MCP adapter. That is not a criticism of Imagify — it is how Composer dependencies work, and every one of those plugins is doing something reasonable in isolation. But it means the honest answer to "did I install an MCP server?" is usually "yes, three times, as a side effect."
Core opted out. Your plugins opted in.
The single most interesting line in the audit is the core row: WordPress registers three abilities and publishes none of them as MCP tools.
| Core ability | Read-only | MCP tool |
|---|---|---|
core/get-site-info | yes | no |
core/get-user-info | yes | no |
core/get-environment-info | yes | no |
Core's three abilities are read-only getters, and even those are not published. The adapter's own three management abilities (discover-abilities, get-ability-info, execute-ability) are likewise not flagged public.
So the entire public tool surface on this site comes from third-party plugins. And they did not all make the same call. WPForms registers eight abilities and publishes only three — the three read-only ones. Its writes (create-form, add-field, update-field, update-form-settings) are deliberately held back. WooCommerce registers seven and publishes all seven, writes included.
Neither choice is wrong. WPForms is being conservative; WooCommerce is enabling genuine agentic commerce workflows, which is the entire point of the exercise. But it is worth knowing that "does this plugin expose write tools to AI agents?" is a per-vendor decision with no house style yet — and no consent prompt telling you which way each one went.
The nine tools that can write — and the four that can destroy
Read tools are the easy case. The ones worth reviewing before you connect anything are the writes.
| Tool | What it does | Destructive |
|---|---|---|
woocommerce/product-delete | Delete, trash, or restore a product | yes |
woocommerce/product-update | Update an existing product's catalogue fields | yes |
woocommerce/order-update-status | Change an order's status | yes |
imagify/optimize-media | Run optimisation over media files | yes |
woocommerce/product-create | Create a product | no |
woocommerce/order-add-note | Add a note to an order | no |
imagify/update-settings | Change Imagify settings | no |
rank-math/fix-site-seo | Apply an automated fix from an SEO audit | no |
rank-math/create-ai-visibility-brand | Create a brand-tracking entry | no |
Two of these deserve a closer look, because the schema is more revealing than the description.
woocommerce/product-delete takes an id and an optional boolean force. Its own schema documents the behaviour plainly: "Permanently delete the product. Defaults to false, which moves the product to trash." The default is the safe one. But the permanent option is one boolean away, and it is in the tool schema an agent reads.
rank-math/fix-site-seo is the one that made me sit up, because this is an SEO blog. It accepts a test_id from a fixed list, and that list includes noindex, robots_txt, sitemaps, opengraph, post_titles and — permalink_structure. Every one of those is a lever with site-wide search consequences. An agent applying a well-intentioned "fix" to your permalink structure is not a data-loss event; it is a URL-change event, which for a site with any organic footprint is arguably worse.
One caveat I want to state clearly rather than bury: readonly and destructive are annotations. In MCP they are hints to the client about how to present a tool, not enforcement. What actually enforces access is the ability's permission callback. Do not read "readonly: true" as a security guarantee — read it as a label the vendor applied.

What the alarming headlines get wrong
There is a claim circulating that the WooCommerce MCP integration exposes customer PII — emails, billing and shipping addresses — "to any connected AI agent by default." I went looking for that, because if it were true it would be the headline.
It is not, in two specific ways.
First, the endpoints are authenticated. I tested them unauthenticated against the live origin:
| Request | Result | What it returns |
|---|---|---|
GET /wp-json/mcp | 200 | The REST route index only — namespace and method list, no tools |
GET /wp-json/wp-abilities/v1/abilities | 401 | rest_forbidden |
POST /wp-json/mcp/mcp-adapter-default-server (tools/list) | 401 | rest_forbidden |
The discovery index answers to anyone — it is a route listing, the same as any other REST namespace, and it reveals nothing about your catalogue. Both routes that would actually enumerate or run tools reject an unauthenticated caller. The adapter's transport gates on its own permission check; the abilities REST controller gates on its.
Second, WooCommerce's MCP integration is behind a feature flag, and on this install it is off. woocommerce_feature_mcp_integration_enabled reads no, as does woocommerce_feature_agentic_checkout_enabled. The abilities are registered and flagged, but the store's own MCP integration is not switched on by default.
The "by default" in that claim is doing a lot of work it has not earned. Check your own values before you act on someone else's screenshot — which is the same lesson as chasing down a deprecation date rather than trusting the coverage, something I wrote about last week in OpenAI model deprecation: check your chatbot before 10 August.
The real risk is blast radius, not the endpoint
So the door is locked. The question that matters is what is on the other side of it once you hand someone a key — and here the picture is genuinely worth thinking about.
When you connect an agent, you do not connect it to a tool. You connect it to the tool list. One authenticated session, 31 tools, including nine that write and four flagged destructive. There is no per-tool consent screen in the protocol, and the WordPress side does not add one. An agent you connected to draft product descriptions has product-delete in the same list.
That is not a vulnerability. It is a scope decision, and it is yours to make — but you have to know you are making it.
The data question is similar. woocommerce/orders-query is read-only and entirely legitimate: it is what makes "where is my order?" answerable. Its output schema includes order id, status, currency, total, customer_id, payment method, timestamps and billing_email. That is exactly the field set a support workflow needs. It is also personal data leaving your database for a third-party model provider the moment an external agent calls it. If you operate in the EU or UK, that is a processing decision with paperwork attached — related to, but separate from, the disclosure duty I covered in the EU AI Act's Article 50 requirements for chatbots.
Audit your own site in one command
Every number in this article came from one WP-CLI call. Run it on your own site:
wp eval 'foreach (wp_get_abilities() as $a) {
$m = (array) $a->get_meta();
$mcp = (array) ($m["mcp"] ?? []);
$ann = (array) ($m["annotations"] ?? []);
printf("%-42s %-8s %s%s\n",
$a->get_name(),
empty($mcp["public"]) ? "private" : "MCP",
empty($ann["readonly"]) ? "WRITE" : "read",
empty($ann["destructive"]) ? "" : " DESTRUCTIVE");
}'
Read the output in this order:
- Count the
MCPlines. That is your actual tool surface, not the plugin count. - Find every
WRITE. For each one, ask whether an agent doing its job should ever need it. If the answer is no, that plugin's ability is a candidate for removal via thewp_abilities_registeredfilter or simply deactivating what you are not using. - Treat every
DESTRUCTIVEas a named risk. Write them down. That short list is what you are actually authorising. - Check your feature flags —
wp option get woocommerce_feature_mcp_integration_enabled— before believing any article about what is on by default. Including this one.
Then verify the doors: curl -s -o /dev/null -w "%{http_code}" -X POST https://yoursite.com/wp-json/mcp/mcp-adapter-default-server -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'. You want a 401. If you get a 200 with a tool list, stop and fix that today.
Where a chatbot plugin fits in this picture
An honest note on our own position, since we sell in this category.
MxChat ships an MCP server add-on, documented in the MxChat MCP Server docs, and it makes the same category of decision every vendor above made. The argument for a chatbot plugin owning that layer is not that it is more secure by nature — it is that a chatbot plugin is where the conversation lives, so it is the natural place to scope which tools a given bot can reach, and to keep a transcript of what was called.
A general-purpose adapter publishes tools. A chatbot plugin has a reason to know which visitor is asking, and to answer differently for a logged-out shopper than for a store admin. If you are already running conversational commerce, that context is worth something — I sketched what that looks like in practice in the WooCommerce chatbot guide.
If you are not, the honest advice is the boring advice: run the audit, disable what you do not use, and do not connect an agent to a production store until you can name the four destructive tools it inherits.
Frequently asked questions
Does installing WooCommerce turn my site into an MCP server?
It registers seven abilities flagged as MCP tools and it vendors an MCP adapter. Whether the store's own MCP integration runs is controlled by the woocommerce_feature_mcp_integration_enabled flag, which read no on the install I audited. Check yours rather than assuming either way.
Can anyone on the internet call these tools?
Not on a correctly configured site. Both the abilities REST controller and the MCP transport returned 401 to unauthenticated requests in my testing. The public /wp-json/mcp route returns a route index only. Verify it on your own domain with the curl command above.
What does "destructive" mean in the tool metadata?
It is an MCP annotation — a hint to the client that the tool makes changes that are hard to undo, so a well-behaved client can prompt before calling it. It is advisory. Enforcement lives in the ability's permission callback, not the annotation.
How do I remove an ability I do not want exposed?
The cleanest answer is usually to deactivate the plugin that registers it, since an ability you cannot use is a symptom of a plugin you are not using. Where you need the plugin but not the tool, abilities can be unregistered on the wp_abilities_registered hook. Test on staging — some plugins consume their own abilities internally.
Should I connect Claude or ChatGPT to my WooCommerce store?
It is a reasonable thing to do for catalogue work and support triage, and it is not a reasonable thing to do casually on a store taking live orders. The deciding question is not "is MCP safe" but "am I comfortable that this session can call product-delete and read billing_email." If that sentence makes you uneasy, narrow the tool surface first.
The short version
Your WordPress site probably has more of an AI surface than you chose. It is authenticated, so it is not an open door — but it is a wide one, and it grew there through ordinary plugin updates rather than a decision.
Run the one-liner. Count your writes. Name your destructive tools. That is a fifteen-minute job that turns an unknown into a list, and a list is something you can actually manage.